【问题标题】:freeing malloced memory bug free释放分配的内存错误
【发布时间】:2017-03-22 09:14:01
【问题描述】:

我是一个自我狂热的 CS 学习者。 (请把我的 cmets 作为一个极客的查询,以获得他需要的进一步澄清) 我正在编写一个简单的 c 脚本来更好地理解动态分配的内存(除了队列和堆)。为此,我创建了一个简单的“malloced”指针,指向“n int 类型的堆内存”。
int *array;
    int size = 10;
    //point to a chunk of 10 (m)allocated memory in heap (?) am I right ? 
    array = (int *) malloc(sizeof(int) * size);

现在我对它们做了一些操作。例如

//passing array as reference (?)

void handy_array(int *pointer, int size) {

    /*operation on the (m)allocated array of given size created in heap*/

    for(int i = 0; i < size; i++) {
        pointer[i] = i-10 ;
    }
    return;
}

到目前为止一切顺利,现在我们可以像使用 char string[n] = "a string" 一样使用这个数组 [size]。 但是当使用这种方法释放内存时

void free_array(int *array, int size) {

    for(int i= 0; i < size; i++){
        //free the ith assigned address and its value in heap memory
        free(&array[i]);

    }
    return;
}

现在,我收到了这条有趣的错误消息-

    *** Error in `./main': free(): invalid pointer: 0x0973d00c ***
======= Backtrace: =========
/lib/i386-linux-gnu/libc.so.6(+0x67377)[0xb75f6377]
/lib/i386-linux-gnu/libc.so.6(+0x6d2f7)[0xb75fc2f7]
/lib/i386-linux-gnu/libc.so.6(+0x6dbb1)[0xb75fcbb1]
./main[0x8048590]
./main[0x80484c8]
/lib/i386-linux-gnu/libc.so.6(__libc_start_main+0xf7)[0xb75a7637]
./main[0x8048391]
======= Memory map: ========
08048000-08049000 r-xp 00000000 08:01 22937845   /directory/to/the/script
08049000-0804a000 r--p 00000000 08:01 22937845   /directory/to/the/script
0804a000-0804b000 rw-p 00001000 08:01 22937845   /directory/to/the/script
0973d000-0975e000 rw-p 00000000 00:00 0          [heap]
b7400000-b7421000 rw-p 00000000 00:00 0 
b7421000-b7500000 ---p 00000000 00:00 0 
b7559000-b7575000 r-xp 00000000 08:01 13239646   /lib/i386-linux-gnu/libgcc_s.so.1
b7575000-b7576000 rw-p 0001b000 08:01 13239646   /lib/i386-linux-gnu/libgcc_s.so.1
b758f000-b773e000 r-xp 00000000 08:01 13239459   /lib/i386-linux-gnu/libc-2.23.so
b773e000-b773f000 ---p 001af000 08:01 13239459   /lib/i386-linux-gnu/libc-2.23.so
b773f000-b7741000 r--p 001af000 08:01 13239459   /lib/i386-linux-gnu/libc-2.23.so
b7741000-b7742000 rw-p 001b1000 08:01 13239459   /lib/i386-linux-gnu/libc-2.23.so
b7742000-b7745000 rw-p 00000000 00:00 0 
b775d000-b7760000 rw-p 00000000 00:00 0 
b7760000-b7762000 r--p 00000000 00:00 0          [vvar]
b7762000-b7763000 r-xp 00000000 00:00 0          [vdso]
b7763000-b7785000 r-xp 00000000 08:01 13239455   /lib/i386-linux-gnu/ld-2.23.so
b7785000-b7786000 rw-p 00000000 00:00 0 
b7786000-b7787000 r--p 00022000 08:01 13239455   /lib/i386-linux-gnu/ld-2.23.so
b7787000-b7788000 rw-p 00023000 08:01 13239455   /lib/i386-linux-gnu/ld-2.23.so
bf7eb000-bf80c000 rw-p 00000000 00:00 0          [stack]
Aborted (core dumped)

我的确切问题是:
0. 这是从全局或本地范围分配内存块的实际做法,或者从主方法启动它们并使用我在这里做的本地方法。
1. 上述场景中释放内存的具体方法是什么?

(可选;如果您认为不相关,请忽略)
2. 我想要一些提示来理解有趣的错误信息,比如回溯和内存映射
提前致谢

【问题讨论】:

  • C 不是脚本语言。您应该阅读How to Ask 并提供minimal reproducible example。旁注:一般不要投射malloc & friends 或void * 的结果。
  • 一个 malloc 后面跟着一个 free,而不是 10 个 free。

标签: c pointers memory memory-management


【解决方案1】:

首先,你不需要在下面的语句中转换malloc()的返回值:

array = (int *) malloc(sizeof(int) * size);
//instead use:
array = malloc(sizeof(*array) * size); 
//this is fine and here `*array` instead of `int` to denote the type

原因如下:https://stackoverflow.com/a/605858/5281962


遇到你的问题,你只需要释放你的 malloced 指针一次,但是你在你的 for 循环中使用 free() 不止一次这样做free_array()函数

for(int i= 0; i < size; i++){
    //free the ith assigned address and its value in heap memory
    free(&array[i]);
}

而不是循环只是这样做:

free(array); //done!

【讨论】:

  • 因此,橱柜不再是您的橱柜,其内容现在未定义。它只是还没有被回收。
  • 正如我所说,橱柜的内容还没有被替换,但是当它被替换时,你就会解开。为什么你free还想访问内存呢?我不明白你……假设你租了一辆车,然后把它还给租车公司。当你离开时,你会说“嘿!那辆车还在,我还能继续用吗?”
  • @ph03n1x 当您释放内存时,您只是在告诉操作系统您不再需要它。对于大多数应用程序(安全除外),“清除”内存会浪费周期(这甚至会做什么?一堆 0 或 Fs 当然也可以是有效数据)。在free 之后,您可能仍然可以读取您的数据,但您不能指望它,因为您不再拥有它。操作系统可以免费获取。当您从硬盘驱动器中删除文件时,概念相同。操作系统实际上并没有删除它。这些扇区只是被标记为可以被覆盖。
  • @ph03n1x 这被标记为c++ 并且正在谈论变量范围,但概念是相同的:stackoverflow.com/questions/6441218/…
猜你喜欢
  • 2021-11-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-09
  • 1970-01-01
  • 2011-05-13
  • 1970-01-01
  • 2010-09-21
相关资源
最近更新 更多