在 malloc() 的 char 指针上调用 free() 会导致程序因指针无效而崩溃

标签 c pointers memory-management

当我遇到这个时,我正在学习 C 并玩了一下堆内存:

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

int main(void) {
    char* test = malloc(1024);
    test = "Hello!";
    printf("%s\n", test);
    free(test);
    return 0;
}

我认为它应该做什么:

  • 在堆上分配 1024 个字节
  • 将“Hello!\0”写入该内存的开头
  • 从我从 malloc() 获得的指针的开头写入 stdout 直到找到 \0
  • 释放使用 malloc()
  • 分配的 1024 字节内存
  • 返回 0

但是,当调用 free() 时,我的程序就会崩溃。为什么?

~$ ./mem                                                                                                                                                              
Hello!
*** Error in `./mem': munmap_chunk(): invalid pointer: 0x0000000000400684 ***
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(+0x77725)[0x7f9f99ac5725]
/lib/x86_64-linux-gnu/libc.so.6(cfree+0x1a8)[0x7f9f99ad1c18]
./mem[0x4005ec]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf0)[0x7f9f99a6e830]
./mem[0x4004e9]
======= Memory map: ========
00400000-00401000 r-xp 00000000 08:01 3801151                            /home/gala/mem
00600000-00601000 r--p 00000000 08:01 3801151                            /home/gala/mem
00601000-00602000 rw-p 00001000 08:01 3801151                            /home/gala/mem
015e6000-01607000 rw-p 00000000 00:00 0                                  [heap]
7f9f99838000-7f9f9984e000 r-xp 00000000 08:01 1970703                    /lib/x86_64-linux-gnu/libgcc_s.so.1
7f9f9984e000-7f9f99a4d000 ---p 00016000 08:01 1970703                    /lib/x86_64-linux-gnu/libgcc_s.so.1
7f9f99a4d000-7f9f99a4e000 rw-p 00015000 08:01 1970703                    /lib/x86_64-linux-gnu/libgcc_s.so.1
7f9f99a4e000-7f9f99c0e000 r-xp 00000000 08:01 1970665                    /lib/x86_64-linux-gnu/libc-2.23.so
7f9f99c0e000-7f9f99e0d000 ---p 001c0000 08:01 1970665                    /lib/x86_64-linux-gnu/libc-2.23.so
7f9f99e0d000-7f9f99e11000 r--p 001bf000 08:01 1970665                    /lib/x86_64-linux-gnu/libc-2.23.so
7f9f99e11000-7f9f99e13000 rw-p 001c3000 08:01 1970665                    /lib/x86_64-linux-gnu/libc-2.23.so
7f9f99e13000-7f9f99e17000 rw-p 00000000 00:00 0 
7f9f99e17000-7f9f99e3d000 r-xp 00000000 08:01 1970637                    /lib/x86_64-linux-gnu/ld-2.23.so
7f9f9a013000-7f9f9a016000 rw-p 00000000 00:00 0 
7f9f9a039000-7f9f9a03c000 rw-p 00000000 00:00 0 
7f9f9a03c000-7f9f9a03d000 r--p 00025000 08:01 1970637                    /lib/x86_64-linux-gnu/ld-2.23.so
7f9f9a03d000-7f9f9a03e000 rw-p 00026000 08:01 1970637                    /lib/x86_64-linux-gnu/ld-2.23.so
7f9f9a03e000-7f9f9a03f000 rw-p 00000000 00:00 0 
7ffcc81cb000-7ffcc81ec000 rw-p 00000000 00:00 0                          [stack]
7ffcc81f8000-7ffcc81fa000 r--p 00000000 00:00 0                          [vvar]
7ffcc81fa000-7ffcc81fc000 r-xp 00000000 00:00 0                          [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]
[1]    12941 abort      ./mem

最佳答案

正如评论中所说,这就是发生的事情:

int main(void) {
    char* test = malloc(1024);     /* You allocate, great! */
    test = "Hello!";               /* Huh, what's this? You point 'test' 
                                    * to some area in the code section.
                                    * Valid, but considering you just 
                                    * allocated some memory, strange */
    printf("%s\n", test);          /* Print out a string from the code
                                    * section: fine. */
    free(test);                    /* What?! You want to try to free() the
                                    * memory in the code section? That's a 
                                    * big no-no! */
    return 0;                      /* whatever */
}

现在,你应该做什么:

int main(void) {
    char* test = malloc(1024);     /* You allocate, great! */
    strcpy(test, "Hello!");        /* Copy some data into that 
                                    * allocated memory */
    printf("%s\n", test);          /* Print out a string from the
                                    * heap: fine. */
    free(test);                    /* Free that allocated memory! */
    return 0;                      /* aaaand, we're done */
}

关于在 malloc() 的 char 指针上调用 free() 会导致程序因指针无效而崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38545349/

相关文章:

c - int 数组大小变化

c - 如何保持运行总计

c - 获取位域的值

c++ - C++中声明指针指针的效率

c++ - 将数据复制到类的另一个成员时,类的成员指针会被丢弃

iphone - 单例类中的 NSMutableArray 总是返回计数 0/从不保留其对象

c++ - 是否可以从在 Wine 中运行的 Windows 应用程序调用 native Linux API?

C: 指针类型之间的非法转换:指向 const unsigned char 的指针 -> 指向 unsigned char 的指针

Java 对象数组内存要求

memory-management - OpenCl 清理导致段错误