代码之家  ›  专栏  ›  技术社区  ›  brneuro

让valgrind开心vs避免segfault

  •  2
  • brneuro  · 技术社区  · 6 年前

    我是C语言的新手,尝试学习char数组的动态内存分配,不知道为什么我不能让valgrind在避免segfault的同时也对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'd**myChar和myChar[it]是free(),我取消了注释位,但程序segfaults和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 回复  |  直到 6 年前
        1
  •  1
  •   dbush    6 年前

    您没有分配足够的内存:

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

    这为单个 char * ,但您将此内存视为分配了5(即。 nEl )其中之一。

    因此,您的写入超过了分配内存的末尾。这就是Valgrind提醒您的“地址0x52040408是分配大小为8的块后的0字节”。这样做会调用未定义的行为,在本例中表现为崩溃。

    如果你想要空间 内尔 指针,分配该数量的空间:

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

    而且 don't cast the return value of malloc .