Valgrind Uninitialized Values ​​(Creating a Linked Data Structure)

I created a linked list class, but this function throws valgrind errors saying that there is a conditional branch based on the uninitialized value in this function. I'm not quite sure what I need to do to fix this.

Essentially, there is a node class for the linked list, and it iterates through all the nodes, checking if the key parameter matches the previous node, and if it returns a 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 re-recognized the origin of valgrind tracking, and this is the result:

 ==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 could come from the parse_ dictionary, so I will post this 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; } 
+4
source share
3 answers

Type lines

 char key_word[key_length]; 

look very suspicious.

I don’t know what you’re going to do next, but creating a temporary array of variable length for things that should be constant longer than calling the function seems very strange.

In addition, a variable-length array does not include the trailing '\0' .

+1
source

You are not correctly null-turning off strings in key_word and value_word , and this error is apparently spreading across. This loop is a problem:

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

It copies the key_length characters to key_word , but none of these copied characters is a null terminator. You can fix the problem by adding one extra byte to key_word :

 char key_word[key_length + 1]; 

Then adding this after the for() loop:

 key_word[key_length] = '\0'; 

There is also no need to create copies in <T29> and finalvalue (which are of the wrong type, in any case - that’s why you ultimately need all these ugly casts). Therefore, in general, it would look like this:

 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); 

Indeed, you should simplify this function using the tools from string.h . For example, strstr() will allow you to search for ": " string that separates the key and value, and memcpy() makes the equivalent of these for() loops:

 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; } 
+1
source

If your program is working correctly, do not worry about these warnings. I saw a warning of conditional transition to programs that otherwise work fine. This is probably due to the build code generated by the compiler and not directly related to your code.

-2
source

All Articles