strstr valgrind error

2019-03-05 08:42发布

问题:

I need some help with char* initialization and strstr in C. This is the general issue:

I have a function func1

func1() func2();

The issue is that valgrind gives an error basically saying that strstr might be using an uninitialized value. To rectify this, I'd have to do something like char* str = "hello world";, but then I can't realloc, which is an issue.

I have tested my program with random strings and the issue is the fact that valgrind is treating str as uninitialized, but I just don't know how to initialize it without getting rid of the ability to realloc. Any suggestions?

The error is:

==14356== Conditional jump or move depends on uninitialised value(s)
==14356==    at 0x4C29313: strstr (in path)
==14356==    by 0x401983: func2 (in path)
==14356==    by 0x401B06: func1 (in path)
==14356==    by 0x4013D7: main (in path)
==14356== 
==14358== Syscall param execve(argv[i]) points to uninitialised byte(s)
 at 0x4ECFCB7: execve (in path)
==14308==    by 0x4E6A76C: do_system (in path)
==14308==    by 0x4013ED: main 

Edited: Added in the actual functions, changed names and such.

回答1:

In your func1 you have the following:

        str = realloc(str, (stringLen + currExpLen) * sizeof(char)+2);
        sprintf(str, "%s %s", str, currExp);

Using the same string on both sides of sprintf is probably a bad idea. As the output is written its going to clobber the input (str) which could result in any manner of unexpected behaviors. realloc takes care of whatever copying might be needed, so your sprintf could be replaced by some strcats:

        str = realloc(str, (stringLen + currExpLen) * sizeof(char)+2);
        strcat(str, " ");
        strcat(str, currExp);


回答2:

I believe this is your problem:

In func2:

    str = realloc(str, (stringLen + pathLen+1)*sizeof(char));

    memmove(&str[rplcIndx + pathLen], &str[rplcIndx+2], stringLen-rplcIndx-2);
    memcpy(&str[rplcIndx], path, pathLen);

The memmove doesn't copy the null terminator (it is at position stringLen, but the last byte copied would be rpcIndx+2+stringLen-rpcIndx-2-1 = stringLen-1 (remember src[len] is the first byte NOT copied). This means

  • the position of the null terminator is not initialized
  • the string is possibly not correctly terminated

BTW, if you can, using asprintf is safe, easy and fool-proof way of doing many string-manipulation tasks, although it may be a little less effective.