valgrind中的条件跳转或移动错误

时间:2016-03-22 19:20:18

标签: c

我正在尝试使用valgrind来检测内存错误。 这是我的代码的一部分 -

else
{
137.    printf("HELlo\n");  
138.    char * lexeme1;char * lexeme2;
139.    lexeme1=substr1(bufferOld,beginPointer,sizeBuffer-1);
140.    lexeme2=substr1(buffer,0,indexStart-1);
141.    strcat(lexeme,lexeme1);
142.    strcat(lexeme,lexeme2);
}

Token  getNextToken( int fp1, FILE * fp)
{
  ...
  207. lexeme=(char *)malloc(sizeof(char) * 100);
  ...
}

运行valgrind后,它会出现以下错误 -

==9720== Conditional jump or move depends on uninitialised value(s)
==9720==    at 0x4C2DD9A: strcat (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==9720==    by 0x401048: updateToken (lexer.c:141)
==9720==    by 0x402A92: getNextToken (lexer.c:498)
==9720==    by 0x400A17: main (driver.c:66)
==9720==  Uninitialised value was created by a heap allocation
==9720==    at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==9720==    by 0x4012C6: getNextToken (lexer.c:207)
==9720==    by 0x400A17: main (driver.c:66)
==9720== 

我不确定为什么会遇到这类错误。任何帮助都将受到高度赞赏。

更新 -

这是我的substr1函数 -

char * substr1(char * source,int start,int end)
{

    char * dest=malloc((end-start+2)*sizeof(char));
    if(end==-1)
        return dest;
    int i,count=0;
    for(i=start;i<=end;i++)
        dest[count++]=source[i];
    dest[count]='\0';
    return dest;
}

2 个答案:

答案 0 :(得分:4)

这两行

  strcat(lexeme,lexeme1);
  strcat(lexeme,lexeme2);

连接到lexeme,后者又指向未初始化的内存,在此处分配:

  lexeme=(char *)malloc(sizeof(char) * 100);

要解决此问题,请通过调用以下方式显式初始化内存:

  memset(lexeme, 0, 100);

或隐式使用calloc()代替malloc()

  lexeme = calloc(100, 1);

<强>更新

Michihis comment提及的第三个选项是通过调用strcat()

替换第一次调用strcpy()
  strcpy(lexeme, lexeme1);
  strcat(lexeme, lexeme2);

这可能是最便宜的解决方案,至少就速度而言。

在任何情况下,将无用的强制转换移至(char*),并将sizeof char替换为1,而不是{{1}}。

答案 1 :(得分:1)

如@ Alk的答案(+1)所示,中心问题是连接到未初始化的内存(需要从创建内存开始,以及lexeme的初始化)。但是这里有一些避免内存创建/使用问题的其他建议:

因为sizeof(char);始终为1,所以可以编写malloc语句:

char * dest=malloc((end-start+2));

但是因为malloc()没有初始化它创建的内存,并且由于你所看到的问题的性质,我建议另外两件事:

1)检查 source start end 的值,然后在内存分配语句中使用它们。

2)使用calloc()而不是malloc(),因为它会将所有内存初始化为已知值:

char * dest=calloc((end-start+2), 1);