Valgrind 未初始化值(制作链表数据结构)
我创建了一个链表类,但该函数会产生 valgrind 错误,因为该函数中存在基于未初始化值的条件跳转。我不太确定需要做什么来修复它。
本质上,链表有一个节点类,它会迭代所有节点,检查关键参数是否与预先存在的节点匹配,如果匹配则返回值。
const char *dictionary_get(dictionary_t *d, const char *key)
{
node* current;
current = d->head;
if(strcmp(current->key,key)==0)
return current->value;
while(current->next != NULL){
current = current->next;
if(current!=NULL && strcmp(current->key,key)==0)
return current->value;
}
return NULL;
}
有什么想法吗?
我已经重新检查了 valgrind 跟踪起源,这是输出:
==25042== Conditional jump or move depends on uninitialised value(s)
==25042== at 0x4A06E6A: strcmp (mc_replace_strmem.c:412)
==25042== by 0x400DD6: dictionary_get (libdictionary.c:143)
==25042== by 0x400826: main (part2.c:84)
==25042== Uninitialised value was created by a stack allocation
==25042== at 0x400AE3: dictionary_parse (libdictionary.c:69)
==25042==
==25042== Conditional jump or move depends on uninitialised value(s)
==25042== at 0x4A06E8A: strcmp (mc_replace_strmem.c:412)
==25042== by 0x400DD6: dictionary_get (libdictionary.c:143)
==25042== by 0x400826: main (part2.c:84)
==25042== Uninitialised value was created by a stack allocation
==25042== at 0x400AE3: dictionary_parse (libdictionary.c:69)
==25042==
==25042== Conditional jump or move depends on uninitialised value(s)
==25042== at 0x400DD9: dictionary_get (libdictionary.c:143)
==25042== by 0x400826: main (part2.c:84)
==25042== Uninitialised value was created by a stack allocation
==25042== at 0x400AE3: dictionary_parse (libdictionary.c:69)
看起来这可能来自dictionary_parse,所以我也会发布该函数。
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've created a linked list class, but this function is producing valgrind errors based saying that there is a conditional jump based upon an uninitialized value in this function. I'm not exactly sure what I need to do to fix it.
Essentially there is a node class for the linked list and this is iterating over all the nodes checking if the key parameter matches a pre-existing node and if it does it returns the value.
const char *dictionary_get(dictionary_t *d, const char *key)
{
node* current;
current = d->head;
if(strcmp(current->key,key)==0)
return current->value;
while(current->next != NULL){
current = current->next;
if(current!=NULL && strcmp(current->key,key)==0)
return current->value;
}
return NULL;
}
Any ideas?
I've reexamined with valgrind tracking origins and this is the output:
==25042== Conditional jump or move depends on uninitialised value(s)
==25042== at 0x4A06E6A: strcmp (mc_replace_strmem.c:412)
==25042== by 0x400DD6: dictionary_get (libdictionary.c:143)
==25042== by 0x400826: main (part2.c:84)
==25042== Uninitialised value was created by a stack allocation
==25042== at 0x400AE3: dictionary_parse (libdictionary.c:69)
==25042==
==25042== Conditional jump or move depends on uninitialised value(s)
==25042== at 0x4A06E8A: strcmp (mc_replace_strmem.c:412)
==25042== by 0x400DD6: dictionary_get (libdictionary.c:143)
==25042== by 0x400826: main (part2.c:84)
==25042== Uninitialised value was created by a stack allocation
==25042== at 0x400AE3: dictionary_parse (libdictionary.c:69)
==25042==
==25042== Conditional jump or move depends on uninitialised value(s)
==25042== at 0x400DD9: dictionary_get (libdictionary.c:143)
==25042== by 0x400826: main (part2.c:84)
==25042== Uninitialised value was created by a stack allocation
==25042== at 0x400AE3: dictionary_parse (libdictionary.c:69)
It looks like this might be coming from dictionary_parse so I'll post that function too.
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;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
像这样的线条
看起来非常可疑。
我不知道你对这些进一步做了什么,但是为那些应该比函数调用持续更长时间的东西创建一个临时的可变长度数组似乎很奇怪。
另外,可变长度数组不包含终止符
'\0'
。Lines like
look highly suspicious.
I don't know what you do with these further along, but creating a temporary variable length array for things that should be persistent for longer than the function call seems very strange.
Also, the variable length array does not include the terminating
'\0'
.您没有正确地以 null 终止
key_word
和value_word
中的字符串,并且此错误显然正在传播。这个循环就是问题所在:它将
key_length
字符复制到key_word
中,但这些复制的字符都不是空终止符。您可以通过向key_word
添加一个额外的字节来解决该问题:然后在
for()
循环之后添加此字节:也无需在
中创建副本Finalkey
和finalvalue
(无论如何,它们的类型都是错误的 - 这就是为什么你最终需要所有这些丑陋的强制转换)。总的来说,它看起来像这样:实际上,您应该使用
string.h
中的设施来简化这个函数。例如,strstr()
可让您搜索分隔键和值的": "
字符串,而memcpy()
则执行以下操作:相当于这些for()
循环:You are not properly null-terminating the strings in
key_word
andvalue_word
, and this error is apparently propagating through. This loop is the problem:It copies
key_length
characters intokey_word
, but none of those copied characters is a null-terminator. You can fix the problem by adding one extra byte tokey_word
:Then adding this after the
for()
loop:There is also no need to create the copies in
finalkey
andfinalvalue
(which have the wrong type, anyway - which is why you end up needing all those ugly casts). So overall it would look like this:Really though, you should simplify this function using the facilities from
string.h
. For example,strstr()
will let you search for the": "
string that separates your key and value, andmemcpy()
does the equivalent of thosefor()
loops:如果您的程序工作正常,则不必担心这些警告。我见过程序上的条件跳转警告,否则这些程序可以完美运行。它可能与编译器生成的汇编代码有关,与您的代码没有直接关系。
If your program works correctly, don't bother about those warnings. I've seen the conditional jump warning on programs that otherwise work perfectly. It probably has to do with the assembly code generated by the compiler and not directly related to your code.