我正在尝试创建一个链表,将存储单词和它们在.txt文件中发生的次数。在阅读之前,我试图创建一个链表,看看它是否可以。当测试时,它正在崩溃。
#include <iostream>
#include <string>
struct n {
std::string word;
int occurance;
n* next;
};
typedef n node;
int main() {
node* root;
root = (node*)malloc(sizeof(node*));
root->word = "test";
root->occurance = 5;
std::cout << root->word
<< root->occurance << std::endl;
}
误差root = (node*)malloc(sizeof(node*));
在两个方面是错误的。你应该使用
root = new node;
首先,您的代码将为node*
分配空间(通常为4或8字节),而不是为node
分配空间。
其次,malloc
只分配内存,但不初始化内存。参见在什么情况下使用malloc和/或new?1这意味着新分配的node
的所有成员都有不确定的值,读取它们将导致未定义的行为。在您的情况下,这显示为访问违反。
1在现代c++中你应该避免这两个;)
malloc
是C语言的延续,这是C语言在上个世纪的发展方式。它可以编译,但这主要是运气不好。
至少移动到1998,并使用std::list
,或者std::map<std::string, int>
。解释为什么过时的技术会失败是没有用的。
sizeof(node*)
获取指向node
的指针的大小。可能是4或8个字节。malloc(sizeof(node*))
分配了那么多字节
但是node
比指向node
的指针大。因此,您的代码填充所有数据,并超过它分配的内存的末尾,因为它只为指针分配了足够的空间
方案一:将malloc(sizeof(node*))
改为malloc(sizeof(node))
解决方案2:将(node*)malloc(sizeof(node*))
更改为new node
,因为它是c++(而不是C),您可以这样做。
另外,不要忘记释放它(free(root);
为malloc
或delete node;
为new
)。当程序结束时,操作系统会自动释放你所有的东西,所以这在这个简短的程序中并不重要,但是当你制作一个做很多事情的程序时,你必须从一部分释放内存,以便下一部分可以重用它。