C malloc() 在 linux 上抛出错误,而不是在 mac 上

标签 c linux macos malloc

我有一个函数可以解析文件并计算一些内容。功能如下:

int meta_counter(FILE *meta_file){
    int counter = 0;
    char *c;
    char line[1024];
    while ((c = fgets(line, sizeof(line), meta_file)) != NULL)
    {
        char *first = malloc(sizeof(c));
        strcpy(first,c);
        char *rest = strchr(first, ' ');
        *rest = 0;
        if (strcmp(first,"Start") != 0 && strcmp(first,"End") != 0) {
            //handle typos
            char *d = remove_white_spaces(c);
            replace_string(d,';',':');
            replace_string(d,'.',':');
            char *e = (char*)malloc(sizeof(d) + 1);
            remove_string(e, d, ' ');
            // put a ':' at the end of the line
            if (e[strlen(e)-1] != ':') e[strlen(e)] = ':';
            //count operators in line 'e'
            char *key = ":";
            char *ptr = e;
            while((ptr = strchr(ptr, ':')) != NULL) {
                counter++;
                ptr++;
            }
        }
    }
    rewind(meta_file);
    return counter;
}

当我在 Mac OSX 上编译并运行该程序时,一切都很顺利。但是当我编译(编译没有问题)并在Linux上运行时,它给了我这样的错误:

*** Error in `./sim01': malloc(): memory corruption: 0x0000000001bc7170 ***
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(+0x77725)[0x7f4cf974a725]
/lib/x86_64-linux-gnu/libc.so.6(+0x819be)[0x7f4cf97549be]
/lib/x86_64-linux-gnu/libc.so.6(__libc_malloc+0x54)[0x7f4cf97565a4]
./sim01[0x4013d7]
./sim01[0x401f8b]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf0)[0x7f4cf96f3830]
./sim01[0x400a99]
======= Memory map: ========
00400000-00403000 r-xp 00000000 08:05 3145767                            /home/pregis/workspace/cpp-mars/Sim01/sim01
00602000-00603000 r--p 00002000 08:05 3145767                            /home/pregis/workspace/cpp-mars/Sim01/sim01
00603000-00604000 rw-p 00003000 08:05 3145767                            /home/pregis/workspace/cpp-mars/Sim01/sim01
01bc6000-01be7000 rw-p 00000000 00:00 0                                  [heap]
7f4cf4000000-7f4cf4021000 rw-p 00000000 00:00 0 
7f4cf4021000-7f4cf8000000 ---p 00000000 00:00 0 
7f4cf94bd000-7f4cf94d3000 r-xp 00000000 08:05 25559117                   /lib/x86_64-linux-gnu/libgcc_s.so.1
7f4cf94d3000-7f4cf96d2000 ---p 00016000 08:05 25559117                   /lib/x86_64-linux-gnu/libgcc_s.so.1
7f4cf96d2000-7f4cf96d3000 rw-p 00015000 08:05 25559117                   /lib/x86_64-linux-gnu/libgcc_s.so.1
7f4cf96d3000-7f4cf9893000 r-xp 00000000 08:05 25559903                   /lib/x86_64-linux-gnu/libc-2.23.so
7f4cf9893000-7f4cf9a92000 ---p 001c0000 08:05 25559903                   /lib/x86_64-linux-gnu/libc-2.23.so
7f4cf9a92000-7f4cf9a96000 r--p 001bf000 08:05 25559903                   /lib/x86_64-linux-gnu/libc-2.23.so
7f4cf9a96000-7f4cf9a98000 rw-p 001c3000 08:05 25559903                   /lib/x86_64-linux-gnu/libc-2.23.so
7f4cf9a98000-7f4cf9a9c000 rw-p 00000000 00:00 0 
7f4cf9a9c000-7f4cf9ac2000 r-xp 00000000 08:05 25559843                   /lib/x86_64-linux-gnu/ld-2.23.so
7f4cf9c91000-7f4cf9c94000 rw-p 00000000 00:00 0 
7f4cf9cbe000-7f4cf9cc1000 rw-p 00000000 00:00 0 
7f4cf9cc1000-7f4cf9cc2000 r--p 00025000 08:05 25559843                   /lib/x86_64-linux-gnu/ld-2.23.so
7f4cf9cc2000-7f4cf9cc3000 rw-p 00026000 08:05 25559843                   /lib/x86_64-linux-gnu/ld-2.23.so
7f4cf9cc3000-7f4cf9cc4000 rw-p 00000000 00:00 0 
7ffcdc988000-7ffcdc9a9000 rw-p 00000000 00:00 0                          [stack]
7ffcdc9c6000-7ffcdc9c8000 r--p 00000000 00:00 0                          [vvar]
7ffcdc9c8000-7ffcdc9ca000 r-xp 00000000 00:00 0                          [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]
Aborted (core dumped)

我发现错误在这一行:char *first = malloc(sizeof(c));。我尝试增加 malloc 函数内部的数字(例如 1000 倍,以确保它可以处理它),以查看 while 循环是否运行多次(它在第二次运行时崩溃),但它只运行了另一个(现在在 3 上崩溃)迭代(应该运行几次)。

我想两个编译器上一定有不同的情况,所以这是我的 gcc 版本:

Mac OSX:

$ gcc -v
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 8.0.0 (clang-800.0.38)
Target: x86_64-apple-darwin15.6.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin

Linux(Ubuntu):

$ gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/5/lto-wrapper
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu 5.4.0-6ubuntu1~16.04.2' --with-bugurl=file:///usr/share/doc/gcc-5/README.Bugs --enable-languages=c,ada,c++,java,go,d,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-5 --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-libmpx --enable-plugin --with-system-zlib --disable-browser-plugin --enable-java-awt=gtk --enable-gtk-cairo --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-5-amd64/jre --enable-java-home --with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-5-amd64 --with-jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-5-amd64 --with-arch-directory=amd64 --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --enable-objc-gc --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.2) 

有什么想法吗?

提前致谢。

最佳答案

当您说 sizeof(c) 时,我确信您希望它返回字符串的大小。它实际上做的是 sizeof(char*),在 64 位平台上通常是 8 个字节。然后将整行复制到其中,这会导致未定义的行为。

接下来,您对 sizeof(d) 执行相同的操作,它也只有 8 个字节。

这对于 sizeof(line) 来说非常不同,因为 linechar[1024] 并且它的大小是已知的。

您可以使用 strdup() 来简化整个代码,它将一次性完成分配和复制。

我在那里看不到任何 free() 调用,这会导致内存泄漏。在循环中尤其糟糕。

请学习如何使用调试器,它会立即显示您分配的内存量不足。并了解如何释放分配的内存。

关于C malloc() 在 linux 上抛出错误,而不是在 mac 上,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39826243/

相关文章:

C 程序中的字符不匹配

java - 无法从java中的shell脚本命令获取输出

java - 无法从 Mac 终端执行 jshell

c - C语言中如何实现同时输入和输出?

c - 包含结构的自由链表包含结构

c - 如何在 C 语言自己的 shell 中使用 bash shell 内置命令?

c++ - 运行路径依赖库在 linux 上构建的程序的链接阶段无法找到其依赖项

macos - 如何在 Mac 上更改 Docker 镜像安装目录?

php - Laravel 验证器 `required` 也因空字符串而失败

c - 当参数相等时 while 循环不会停止