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

时间:2016-10-03 07:15:36

标签: 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) 

有什么想法吗?

提前致谢。

3 个答案:

答案 0 :(得分:4)

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

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

这与sizeof(line)非常不同,因为linechar[1024]且其大小已知。

您可以使用strdup()来简化整个代码,free()将同时执行分配和复制。

我无法在那里看到任何{{1}}个调用,这会导致内存泄漏。在循环中特别糟糕。

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

答案 1 :(得分:0)

在行char *first = malloc(sizeof(c));中,sizeof(c)不会返回字符串的大小,而是返回c指针的大小:8,因为您使用的是64位计算机。

您应该尝试使用:char *first = malloc(sizeof(strlen(c) + 1));来分配正确的尺寸。

另一个解决方案是使用strdup函数:

/* alloctate memory to store string and copy the data*/
char *first = strdup(c);

警告:他们没有free()是您的代码......

答案 2 :(得分:0)

sizeof(c)是指向char的指针的大小。

您可以改用sizeof(line)。 Line是一个数组,sizeof与数组的工作方式不同,它给出了数组中所有元素的总大小。

另一种选择是使用malloc(strlen(c)+1)