The following is the error that I got after running Valrind
valgrind --tool=memcheck --leak-check=full --show-reachable=yes ./out
==12140== Invalid read of size 1
==12140== at 0x4C2DF84: strncat (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==12140== by 0x40100D: createSortedRuns (final.c:178)
==12140== by 0x401297: main (final.c:249)
==12140== Address 0x51fd549 is 0 bytes after a block of size 9 alloc'd
==12140== at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==12140== by 0x400EFD: createSortedRuns (final.c:150)
==12140== by 0x401297: main (final.c:249)
==12140==
我得到的另一个错误是:
==12140== Invalid write of size 1
==12140== at 0x4C2DFD0: strncat (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==12140== by 0x40100D: createSortedRuns (final.c:178)
==12140== by 0x401297: main (final.c:249)
==12140== Address 0x51fd54d is 4 bytes after a block of size 9 alloc'd
==12140== at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==12140== by 0x400EFD: createSortedRuns (final.c:150)
==12140== by 0x401297: main (final.c:249)
==12140==
==12140==
==12140== 250 errors in context 7 of 13:
我得到的另一个错误是:
==12140== Invalid read of size 1
==12140== at 0x4C2DF84: strncat (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==12140== by 0x40100D: createSortedRuns (final.c:178)
==12140== by 0x401297: main (final.c:249)
==12140== Address 0x51fd549 is 0 bytes after a block of size 9 alloc'd
==12140== at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==12140== by 0x400EFD: createSortedRuns (final.c:150)
==12140== by 0x401297: main (final.c:249)
==12140==
以下是该计划的摘要:
void createSortedRuns(int start, int end, char file[]){
FILE *givenFile = NULL;
givenFile=fopen(file,"r+b");
rewind(givenFile);
int i=0;
/*printf("File:%s\n",file);
printf("File Length:%zu\n",strlen(file));*/
char *temp = (char *)malloc(sizeof(char)*strlen(file));
for(i=start; i<end; i++){
fseek(givenFile,0,SEEK_CUR);
fread(&inputBuffer[act_inputBufferSize],sizeof(int),1,givenFile);
act_inputBufferSize++;
if((act_inputBufferSize==max_inputBufferSize) ||(i==(end-1))){
//sort
qsort(inputBuffer,act_inputBufferSize,sizeof(int),compare);
// write to file
strncpy(temp,file,strlen(file));
//int k=0;
char counter[4]={0};
/*for(k=0;k<4;k++){
counter[k]=0;
}*/
snprintf(counter,5, ".%03d", totalSortedFiles);
counter[strlen(counter)] = '\0';
strncat(temp,counter,4);
FILE *int_File = NULL;
int_File=fopen(temp,"w+b");
rewind(int_File);
fwrite(&inputBuffer,sizeof(int),act_inputBufferSize,int_File);
// register the sub_fo information
small_fo=register_sub_fo(small_fo,totalSortedFiles,temp, 0 ,act_inputBufferSize,act_inputBufferSize);
// increase the totalSortedFiles
totalSortedFiles+=1;
// Reinitialize
int j=0;
for(j=0;j<max_inputBufferSize;j++){
inputBuffer[j]=0;
}
act_inputBufferSize=0;
int len = strlen(temp);
temp[len-4] = '\0';
// Garbage
fclose(int_File);
int_File = NULL;
}
} //for_end
fclose(givenFile);
givenFile=NULL;
free(temp);
temp=NULL;
} // func_end
Valgrind显示错误在“strncat(temp,counter,4)”行;“有人可以解释一下我的错误吗?
答案 0 :(得分:1)
strncpy
函数不会将目标缓冲区置零。您在代码中使用strncpy
,它肯定达到了大小限制
strncpy(temp,file,strlen(file));
这意味着此时temp
不会以零结尾。此temp
电话后,strncpy
不是字符串。
之后你做
strncat(temp,counter,4);
但strncat
要求其第一个操作数为字符串。在你的情况下,它不是一个字符串。行为未定义。
正如已多次声明的那样,strncpy
不是有限长度的字符串复制功能。使用它本身是容易出错和跛脚的。即使它可以“工作”,它仍然不适合这项工作。
除此之外,您为temp
分配的缓冲区除了strncpy
之后已存在的字符外,还无法容纳任何其他字符。缓冲区的长度分配为strlen(file)
个字符。
此外,这句话在ll
似乎没有任何意义counter[strlen(counter)] = '\0';
要使strlen
正常工作,您的counter
必须已正确终止。因此,您正在做的是将counter
字符串重新终止于已终止的确切位置。有什么意义呢?
你不需要这样做。 snprintf
已经生成了一个以零结尾的字符串。
但是,您的snprintf
调用本身就存在问题。
char counter[4]={0};
snprintf(counter,5, ".%03d", totalSortedFiles);
您的counter
数组的大小为4。通过将5作为缓冲区大小传递给snprintf
,您将对snprintf
撒谎。一般情况下,snprintf
将超出范围。行为未定义。
您在snprintf
中使用的格式表明您确实需要一个大小为5的缓冲区。