Valgrind / 内存错误
当我使用 valgrind 时,我的代码中反复收到以下错误。我不太确定这些意味着什么,也无法识别未初始化的值。
==16795== Conditional jump or move depends on uninitialised value(s)
==16795== at 0x4A06E8A: strcmp (mc_replace_strmem.c:412)
==16795== by 0x4009C7: dictionary_add (libdictionary.c:44)
==16795== by 0x40061B: main (part2.c:28)
==16795==
==16795== Invalid write of size 1
==16795== at 0x4A082E7: strcpy (mc_replace_strmem.c:303)
==16795== by 0x400AA8: dictionary_add (libdictionary.c:57)
==16795== by 0x40061B: main (part2.c:28)
==16795== Address 0x4c361a3 is 0 bytes after a block of size 3 alloc'd
==16795== at 0x4A05E1C: malloc (vg_replace_malloc.c:195)
==16795== by 0x400931: node_newnode (libdictionary.c:28)
==16795== by 0x400A8C: dictionary_add (libdictionary.c:54)
==16795== by 0x40061B: main (part2.c:28)
我正在创建一个链表数据结构,这些是给出此内存错误时调用的函数。
// 这是节点和字典数据结构的构造。
typedef struct node
{
char* key;
char* value;
struct node* next;
}node;
typedef struct _dictionary_t
{
node* head;
} dictionary_t;
// 首先创建一个新字典
void dictionary_init(dictionary_t *d)
{
d->head = NULL;
d->head = malloc(sizeof(node));
node_init(d->head);
}
// 使用node_init 方法创建一个新节点。
void node_init(node *n)
{
n->key = NULL;
n->value =NULL;
n->key = malloc(sizeof(char));
n->value = malloc(sizeof(char));
n->next = NULL;
}
// 这个新的节点方法在原始初始化之后(当我们添加新术语时)使用。前一个方法专门用于在创建时在结构的开头创建哨兵。
void node_newnode(node *n, int x, int y)
{
n->key = NULL;
n->value = NULL;
n->key = malloc(x*sizeof(char));
n->value = malloc(y*sizeof(char));
n->next = NULL;
}
// 在本例中,还调用此函数将“key”和“value”作为一对添加。
int dictionary_add(dictionary_t *d, const char *key, const char *value)
{
node *current;
current = d->head;
if(strcmp(current->key,key)==0)
return -1;
while(current->next != NULL){
current=current->next;
if(strcmp(current->key,key)==0)
return -1;
}
current->next = NULL;
current->next = malloc(sizeof(node));
node_newnode(current->next,strlen(key),strlen(value));
current = current->next;
strcpy((current->key), key);
strcpy((current->value),value);
return 0;
}
任何人都对我为什么会收到这些错误有任何想法。到目前为止,main 方法仅创建了一个字典并调用了 add 函数。 Valgrind 在 8 次函数调用过程中在 38 个上下文中报告了 45 个以上错误。我认为这些可能是我反复犯的小错误。
我现在也遇到了与此功能相同的错误。 valgrind --track-origins=yes 命令将其跟踪到以下函数中的堆栈分配:
int dictionary_parse(dictionary_t *d, char *key_value)
{
char* colon;
char* space;
colon = key_value;
space = key_value;
space++;
int key_length = -1; //Default key length to check for failure
int i=0;
int j=0; // Loop variables
int k=0;
int length = strlen(key_value);
for(i=0;i<length-2;i++){
if(*colon == ':' && *space == ' '){
key_length = i;
break;
}
colon++;
space++;
}
if(key_length == -1 || key_length == 0)
return -1;
int value_length = length-2-key_length;
colon = key_value;
char key_word[key_length];
key_word[0] = '\0';
char value_word[value_length];
value_word[0] = '\0';
for(j=0;j<key_length;j++){
key_word[j] = *colon;
colon++;
}
space++;
for(k=0; k<value_length;k++){
value_word[k] = *space;
space++;
}
char* finalkey[key_length];
strcpy((char*)finalkey,key_word);
char* finalvalue[value_length];
strcpy((char*)finalvalue,value_word);
dictionary_add(d,(char*)finalkey,(char*)finalvalue);
return 0;
}
谢谢, -新程序员
I'm receiving the following errors repeatedly throughout my code when I use valgrind. I'm not quite sure what these mean and I can't identify the uninitialized values.
==16795== Conditional jump or move depends on uninitialised value(s)
==16795== at 0x4A06E8A: strcmp (mc_replace_strmem.c:412)
==16795== by 0x4009C7: dictionary_add (libdictionary.c:44)
==16795== by 0x40061B: main (part2.c:28)
==16795==
==16795== Invalid write of size 1
==16795== at 0x4A082E7: strcpy (mc_replace_strmem.c:303)
==16795== by 0x400AA8: dictionary_add (libdictionary.c:57)
==16795== by 0x40061B: main (part2.c:28)
==16795== Address 0x4c361a3 is 0 bytes after a block of size 3 alloc'd
==16795== at 0x4A05E1C: malloc (vg_replace_malloc.c:195)
==16795== by 0x400931: node_newnode (libdictionary.c:28)
==16795== by 0x400A8C: dictionary_add (libdictionary.c:54)
==16795== by 0x40061B: main (part2.c:28)
I'm creating a linked-list data structure and these are the functions being called when this memory error is given.
// Here are the constructions of both a node and the dictionary data struct.
typedef struct node
{
char* key;
char* value;
struct node* next;
}node;
typedef struct _dictionary_t
{
node* head;
} dictionary_t;
// First a new dictionary is created
void dictionary_init(dictionary_t *d)
{
d->head = NULL;
d->head = malloc(sizeof(node));
node_init(d->head);
}
// A new node is created using the node_init method.
void node_init(node *n)
{
n->key = NULL;
n->value =NULL;
n->key = malloc(sizeof(char));
n->value = malloc(sizeof(char));
n->next = NULL;
}
// This new node method is used after the original initialization (when we are adding new terms) The previous one is specifically for creating a sentinel at the beginning of the structure upon creation.
void node_newnode(node *n, int x, int y)
{
n->key = NULL;
n->value = NULL;
n->key = malloc(x*sizeof(char));
n->value = malloc(y*sizeof(char));
n->next = NULL;
}
// This function is also being called to add "key" and "value" as a pair in this case.
int dictionary_add(dictionary_t *d, const char *key, const char *value)
{
node *current;
current = d->head;
if(strcmp(current->key,key)==0)
return -1;
while(current->next != NULL){
current=current->next;
if(strcmp(current->key,key)==0)
return -1;
}
current->next = NULL;
current->next = malloc(sizeof(node));
node_newnode(current->next,strlen(key),strlen(value));
current = current->next;
strcpy((current->key), key);
strcpy((current->value),value);
return 0;
}
Anyone have any ideas on why I'm getting those errors. The main method has thus far only created a dictionary and called the add function. Valgrind is reporting 45+ errors over 38 contexts over the course of 8 function calls. I think these are probably small errors that I'm committing repeatedly.
I'm now also getting the same errors with this function. A valgrind --track-origins=yes command traces it to a stack allocation in the following function:
int dictionary_parse(dictionary_t *d, char *key_value)
{
char* colon;
char* space;
colon = key_value;
space = key_value;
space++;
int key_length = -1; //Default key length to check for failure
int i=0;
int j=0; // Loop variables
int k=0;
int length = strlen(key_value);
for(i=0;i<length-2;i++){
if(*colon == ':' && *space == ' '){
key_length = i;
break;
}
colon++;
space++;
}
if(key_length == -1 || key_length == 0)
return -1;
int value_length = length-2-key_length;
colon = key_value;
char key_word[key_length];
key_word[0] = '\0';
char value_word[value_length];
value_word[0] = '\0';
for(j=0;j<key_length;j++){
key_word[j] = *colon;
colon++;
}
space++;
for(k=0; k<value_length;k++){
value_word[k] = *space;
space++;
}
char* finalkey[key_length];
strcpy((char*)finalkey,key_word);
char* finalvalue[value_length];
strcpy((char*)finalvalue,value_word);
dictionary_add(d,(char*)finalkey,(char*)finalvalue);
return 0;
}
Thanks,
-newprogrammer
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
第一个错误(“条件跳转或移动取决于未初始化的值”)是因为
current->key
指向的字符从未初始化。您在node_init()
中为其分配了一个字节,但您从未实际将该字节设置为任何内容。如果您希望head
节点的key
表现得像一个空字符串,请像这样更改node_init()
:第二个错误(“Invalid write of size 1") 是因为您的
node_newnode()
函数分配的字节比字符串所需的少一个字节。strlen(key)
计算字符串中的实际字符数,但空终止符还需要一个字节。使用:(但就我个人而言,我只是将
key
和value
传递给node_newnode()
,并让它同时执行分配和strcpy()
)。The first error ("Conditional jump or move depends on uninitialised value(s)") is because the character pointed to by
current->key
was never initialised. You allocated a byte for it innode_init()
, but you never actually set that byte to anything. If you want thehead
node'skey
to act like an empty string, changenode_init()
like this:The second error ("Invalid write of size 1") is because your
node_newnode()
function is allocating one byte less than is needed for the strings.strlen(key)
counts the actual characters in the string, but one more byte is needed for the null terminator character. Use:(but personally I would just pass
key
andvalue
tonode_newnode()
, and have it do both the allocation and thestrcpy()
).