C语言 未初始化的值是由堆分配创建的
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/27594992/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Uninitialized value was created by a heap allocation
提问by Core_dumped
I'm trying to implement a dictionary of words using a hash table, so I need to have it global, and in one of my header files I declare it
我正在尝试使用哈希表实现单词字典,因此我需要将其设为全局,并在我的一个头文件中声明它
extern node** dictionary;
Where node is
节点在哪里
typedef struct node
{
char* word;
struct node* next;
} node;
Then in another file in which functions are defined I include the header which has the dictionary declaration, and also I add at the top
然后在另一个定义了函数的文件中,我包含了具有字典声明的标题,并在顶部添加
node** dictionary;
Then in the function which actually loads the dictionary I first allocate memory for the linked lists which will make the hash table
然后在实际加载字典的函数中,我首先为链表分配内存,这将使哈希表
bool load(const char* dict_file)
{
dictionary = malloc(sizeof(node*) * LISTS);
FILE* dict = fopen(dict_file, "r");
if(dict == NULL)
return false;
char buffer[MAX_LEN + 2];
size_dict = 0;
while(fgets(buffer, MAX_LEN + 2, dict) != NULL)
{
node* new_node = malloc(sizeof(node));
int len = strlen(buffer);
new_node->word = malloc(sizeof(char) * (len));
//avoid \n
for(int i = 0; i < len - 1; i++)
new_node->word[i] = buffer[i];
new_node->word[len - 1] = 'dictionary = malloc(sizeof(node*) * LISTS);
// .... code that does not change dictionary[i] for any i
new_node->next = dictionary[index]; // use uninitialized pointer
';
new_node->next = NULL;
int index = hash(buffer);
new_node->next = dictionary[index];
dictionary[index] = new_node;
size_dict++;
}
if (ferror(dict))
{
fclose(dict);
return false;
}
fclose(dict);
return true;
}
So the program works fine, I then free all the allocated memory for strings and nodes and when I run valgrind(a debugger which detects memory leaks) it says no memory leaks are possible, but it says that there is an error Uninitilised value was created by a heap allocationand redirects me to that exact line where I'm allocating memory for dictionarythe exact first line of the load function which I've written above.
What am I doing wrong? I guess the way I use dictionaryglobally is wrong, so can anybody suggest some other way of keeping it global and avoid this error?
所以程序运行良好,然后我释放所有分配给字符串和节点的内存,当我运行 valgrind(一个检测内存泄漏的调试器)时,它说没有内存泄漏是可能的,但它说有一个错误Uninitilised value was created通过堆分配并将我重定向到我正在为dictionary上面编写的加载函数的确切第一行分配内存的确切行。
我究竟做错了什么?我想我dictionary在全球范围内使用的方式是错误的,所以有人可以建议一些其他的方式来保持它的全球性并避免这个错误吗?
回答by M.M
In the updated code you use an uninitialized pointer:
在更新的代码中,您使用了一个未初始化的指针:
dictionary = malloc(sizeof(node*) * LISTS);
if ( !dictionary ) {
return false;
}
for (size_t i = 0; i < LISTS; ++i) {
dictionary[i] = NULL;
}
As people had wrote already, this will only work if you had pre-set all the pointers to be NULLbefore entering this loop:
正如人们已经写过的那样,只有NULL在进入这个循环之前你已经预先设置了所有的指针,这才有效:
回答by John Zwinck
The heap allocation you assign to dictionaryuses mallocwhich does not initialize the returned bytes. So dictionaryin the code you've posted ends up being an array of uninitialized pointers. Presumably you go on to use those pointers in some way which valgrind knows to be an error.
您分配给dictionary使用的堆分配malloc不会初始化返回的字节。所以dictionary在你发布的代码中,最终是一个未初始化的指针数组。大概你继续以某种方式使用这些指针,而 valgrind 知道这是一个错误。
An easy way to fix this is to use callocinstead of malloc, because it zeros the returned bytes for you. Or, use memsetto zero the bytes yourself.
解决此问题的一种简单方法是使用calloc而不是malloc,因为它会为您将返回的字节归零。或者,使用memset自己将字节归零。

