我正在尝试使用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;
}
答案 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);
<强>更新强>
Michi中his 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);