使valgrind快乐与避免segfault

时间:2018-02-21 02:51:47

标签: c malloc free

我是C的新手,试图学习一组char数组的动态内存分配,并且不确定为什么我不能让valgrind对0错误感到满意,同时避免了段错误。我的例子基于这个例子:

How to dynamically allocate memory for char** in C

从那个例子中,我在下面提出了这个测试代码:

#include <stdlib.h>
#include <stdio.h>

int main (int argc, char* argv[]){
        char **myChar;

        int nEl = 5;
        int nChars = 10;

        myChar = (char**)malloc(sizeof(char*));
        for (int it = 0; it < nEl; it++) {
                myChar[it] = (char*)malloc((nChars) * sizeof(char));
        }

        //for (int it = 0; it < nEl; it++) {
        //        free(myChar[it]);
        //}
        //free(myChar);

        return 0;
}

它按原样编译,运行没有问题,退出时返回0x0,但valgrind抱怨:

4 errors in context 1 of 1:
Invalid write of size 8
   at 0x400583: main (in /home/username/Documents/personal/tmp/cprog2/test2)
 Address 0x5204048 is 0 bytes after a block of size 8 alloc'd
   at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
   by 0x40054D: main (in /home/username/Documents/personal/tmp/cprog2/test2)

ERROR SUMMARY: 4 errors from 1 contexts (suppressed: 0 from 0)

确定valgrind期望malloc&#39; d ** myChar和myChar [it]是free(),我取消注释注释位,但程序段错误和valgrind说:

4 errors in context 1 of 2:
Invalid read of size 8
   at 0x4005EF: main (in /home/username/Documents/personal/tmp/cprog2/test2)
 Address 0x5204048 is 0 bytes after a block of size 8 alloc'd
   at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
   by 0x40058D: main (in /home/username/Documents/personal/tmp/cprog2/test2)


4 errors in context 2 of 2:
Invalid write of size 8
   at 0x4005C3: main (in /home/username/Documents/personal/tmp/cprog2/test2)
 Address 0x5204048 is 0 bytes after a block of size 8 alloc'd
   at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
   by 0x40058D: main (in /home/username/Documents/personal/tmp/cprog2/test2)

ERROR SUMMARY: 8 errors from 2 contexts (suppressed: 0 from 0)

为什么我不能让valgrind高兴并编译并运行一个有效的应用程序?

1 个答案:

答案 0 :(得分:1)

你没有分配足够的内存:

myChar = (char**)malloc(sizeof(char*));

这为单个char *分配空间,但您将此内存视为已分配5(即nEl)。

结果,您在已分配内存的末尾写入。这就是Valgrind警告你什么时候“地址0x5204048是一个8号块分配后的0字节”。这样做会调用未定义的行为,在这种情况下会表现为崩溃。

如果您想要nEl指针的空间,请分配该空间量:

myChar = malloc(sizeof(char*) * nEl);

另外,don't cast the return value of malloc