运行Valgrind时读取大小1无效

时间:2014-10-28 23:43:53

标签: c gdb valgrind

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)”行;“有人可以解释一下我的错误吗?

1 个答案:

答案 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的缓冲区。