C Valgrind未初始化值(创建链表数据结构)

C Valgrind未初始化值(创建链表数据结构),c,list,linked-list,valgrind,C,List,Linked List,Valgrind,我已经创建了一个链表类,但是这个函数产生了valgrind错误,因为这个函数中有一个基于未初始化值的条件跳转。我不确定我需要做什么来修复它 本质上,链表有一个节点类,它在所有节点上迭代,检查键参数是否与预先存在的节点匹配,如果匹配,则返回值 const char *dictionary_get(dictionary_t *d, const char *key) { node* current; current = d->head; if(strcmp(current->key,ke

我已经创建了一个链表类,但是这个函数产生了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;
}
int dictionary\u parse(dictionary\u t*d,char*key\u值)
{
字符*冒号;
字符*空间;
冒号=键值;
空格=键值;
空间++;
int key_length=-1;//检查失败的默认密钥长度
int i=0;
int j=0;//循环变量
int k=0;
int length=strlen(键值);

对于(i=0;i如果您的程序工作正常,请不要担心这些警告。我已经在其他工作正常的程序上看到了条件跳转警告。它可能与编译器生成的汇编代码有关,而不是与您的代码直接相关。

char key_word[key_length];
看起来非常可疑

我不知道以后如何处理这些函数,但是创建一个临时可变长度数组来处理比函数调用持续时间更长的事情似乎很奇怪


此外,可变长度数组不包括终止的
'\0'
您在
关键字
中终止字符串时未正确使用null,并且此错误显然正在传播。此循环是问题所在:

for(j=0;j<key_length;j++){
  key_word[j] = *colon;
  colon++;
}
然后将其添加到
for()
循环之后:

key_word[key_length] = '\0';
也不需要在
finalkey
finalvalue
中创建副本(无论如何,它们的类型是错误的-这就是为什么您最终需要所有这些难看的类型转换)。因此,总体上看起来是这样的:

char key_word[key_length + 1];
char value_word[value_length + 1];

for (j = 0; j < key_length; j++) {
  key_word[j] = *colon;
  colon++;
}
key_word[key_length] = '\0';

space++;    

for(k = 0; k < value_length; k++) {
  value_word[k] = *space;
  space++;
}
value_word[value_length] = '\0';

dictionary_add(d, key_word, value_word);

嘿,请以与您相同的方式运行Valgrind,但也要使用
--track origins=yes
并将输出粘贴到问题中。此外,您还可以使用
gdb
检查程序,使用
--db attach=yes
哪一行是libdictionary.c中的第69行?哪一行是part2.c中的第84行?part2.c:s=dictionary\ulibdict.c中的(&dictionary,“e”);69:int dictionary\u parse(dictionary\u t*d,char*key\u值){我的错,我需要libdictionary.cAlso中的第143行,你没有包含完整的dictionary_parse-1。绝对没有理由认为它是误报。应该检查它,因为它以后很容易引入错误。@mathepic:我从来没有见过这个特定的警告会导致问题。编译器在优化时会做奇怪的事情这很可能是一个副作用。警告字面上意味着程序的行为将根据一些未初始化内存中的值而改变。这可能是代码中的错误,也可能是编译器的优化程序——就我个人而言,我赌你的代码。
char key_word[key_length + 1];
char value_word[value_length + 1];

for (j = 0; j < key_length; j++) {
  key_word[j] = *colon;
  colon++;
}
key_word[key_length] = '\0';

space++;    

for(k = 0; k < value_length; k++) {
  value_word[k] = *space;
  space++;
}
value_word[value_length] = '\0';

dictionary_add(d, key_word, value_word);
int dictionary_parse(dictionary_t *d, char *key_value)
{
    char *colon;
    char *value;
    int key_length = -1; //Default key length to check for failure

    colon = strstr(key_value, ": ");

    if (colon != NULL) {
        key_length = colon - key_value;  // Number of characters before the colon
        value = colon + 2;  // Value is portion of the string after ": "
    }

    if (key_length < 1) {
        return -1;
    }

    char key_word[key_length + 1];
    memcpy(key_word, key_value, key_length);
    key_word[key_length] = '\0';

    dictionary_add(d, key_word, value);

    return 0;
}