C valgrind中的条件跳转或移动错误
我正在尝试使用C valgrind中的条件跳转或移动错误,c,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);
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;
}
char*substr1(char*source,int-start,int-end)
{
char*dest=malloc((结束-开始+2)*sizeof(char));
如果(结束==-1)
返回目的地;
int i,计数=0;
对于(i=start;i,如@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);
如@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);
这两条线
strcat(lexeme,lexeme1);
strcat(lexeme,lexeme2);
正在连接到lexeme
,这反过来又指向未初始化的内存,分配在此处:
lexeme=(char *)malloc(sizeof(char) * 100);
要解决此问题,请通过调用以下命令显式初始化内存:
memset(lexeme, 0, 100);
或者隐式地使用calloc()
而不是malloc()
:
更新:
如中所述,第三个选项是通过调用strcpy()
至少就速度而言,这可能是最便宜的解决方案
在任何情况下,将无用的强制转换移到(char*)
,并用1
替换char的sizeof
,这两行定义如下。
strcat(lexeme,lexeme1);
strcat(lexeme,lexeme2);
正在连接到lexeme
,这反过来又指向未初始化的内存,分配在此处:
lexeme=(char *)malloc(sizeof(char) * 100);
要解决此问题,请通过调用以下命令显式初始化内存:
memset(lexeme, 0, 100);
或者隐式地使用calloc()
而不是malloc()
:
更新:
如中所述,第三个选项是通过调用strcpy()
至少就速度而言,这可能是最便宜的解决方案
在任何情况下,删除对(char*)的无用强制转换
并用定义上的1
替换sizeof char
。告诉我们substr1
。在发布的片段中,您为词素
分配了内存,但没有将其初始化为C字符串,以便它可以成为strcat
@Noober NO的对象,但这也是一个问题。您正在使用strcat(词素,词素1)
和leseme
也没有初始化。因此,一定要检查malloc
@Nooberstrcat
的返回值,允许将一个内存块附加到另一个内存块。两个内存块都需要以null结尾。在您的情况下,情况并非如此,因此需要strcpy
,记住这一点。无论如何,我都是不是说这两个答案是错误的,但是calloc
的问题是,它的结尾是太多的ZERO
Show-ussubstr1
。在发布的片段中,您为lexeme
分配了内存,但没有将其初始化为C字符串,以便它可以成为strcat
的对象@Noober NO,但这是错误的还有一个问题。您正在使用strcat(lexeme,lexeme1)
和leseme
也没有初始化。因此,一定要检查malloc
@Nooberstrcat
的返回值,允许将一个内存块附加到另一个内存块。两个内存块都需要以null结尾。在您的情况下,情况并非如此,因此需要strcpy
,记住这一点。无论如何,我都是不是说这两个答案是错误的,但是calloc
的问题是,结果是ZERO的问题太多了lexeme
@Michi-lesne?我看不出来。strcpy
是他唯一需要的。@Michi-LOL,是的,人们告诉我的。谢谢。strcat
的问题是,那就是他们也需要strcpy
。所以为了修复它,他们使用calloc
,这没有错,但不完全是他们需要的。问题是lexeme
@Michi-lesne?我看不到。strcpy
是他唯一需要的。@Michi-LOL,是的,有人告诉我。谢谢。strcat
的问题是,t他们也需要strcpy
。所以为了修复它,他们使用calloc
,这没有错,但不完全是他们需要的。strcpy
在那里缺失。@Michi-如果使用calloc创建内存,那么strcat()
可以不被用作第一个副本吗?(即不首先调用strcpy
?)@瑞克:当然可以。@Michi-我想我们是一致的。(这是一个反问:))谢谢。@Ryker