在 C 中调用 free()

标签 c free

当我调用 free(a) 时到底发生了什么?我知道它正在释放使用的内存,但这是否也意味着存储在数组 a 中的数据无法再访问(因此,无法调用 copyArray) ?

int *a = (int *) malloc(sizeof(int) * numberOfInts);
for (i = 0; i < numberOfInts; i++) {
        a[i] = random();
        printf("%d\n", a[i]);
    }
    free(a);
    copyArray(*a++, numberOfInts);

最佳答案

What exactly is happening when I call free(a)?

这是特定于实现的。例如,对于 Linux 和 glibc,可能会发生以下几种情况之一:

如果内存分配在 128k 或更大的 block 中,glibc将分配一个新的内存区域(具体来说,写时复制 mmap/dev/zero )。当它被释放时,内存区域被简单地释放(munmap'd)并消失。进一步的访问将崩溃。

如果分配的内存较小,它将进入堆。堆是从固定地址开始的单个内存区域,其大小可由进程缩小或增加(使用 sbrk )。

内存分配器跟踪分配了该区域的哪些部分。第一次分配东西时,堆的大小增加,内存被追加到这个新空间的末尾。

如果释放这样的内存块,在堆的末尾,堆的大小可以减小,从而使内存无效并使进一步的访问崩溃。不过,分配器不会增加或减少几个字节的堆大小,因此此时它取决于分配的大小和释放的 block 数。它可能是可访问的,也可能不是。

如果您分配十个内存块并释放前九个,您最终会在堆中得到一个未使用的区域。由于您只能通过设置结束地址来修改堆大小,因此您实际上无能为力。内存仍然有效,访问它仍然有效。您甚至可能会在其中找到您的原始数据,并且能够像什么都没发生一样继续。

但是,随着新内存的分配,malloc将尝试将其放入这个未使用的区域,从而让其他数据覆盖原来存在的数据。在你的 free'd 数组中设置一个 int 可能会在你的程序的一个完全不相关的部分覆盖一个指针,并且随之而来的是欢闹和调试。

tl;dr:不要访问释放的内存!

关于在 C 中调用 free(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14986543/

相关文章:

c - 使用动态分配的内存替换字符串

c - 如何释放邻接链表分配的内存?

c - *** 检测到 glibc *** 项目/调试/项目 : free():

python - 使用 free() 时出现无效指针错误

c - 释放堆内存不起作用,因为它应该在 C 中

c - protected 共享内存?

c - 防止输入零作为值的第一个数字

C Gtk+2 Glade3 : how can i set a SourceBuffer to a GtkSourceView that was loaded from glade?

c++ - 类型 'const char*' 和 'const char [93]' 的二进制操作数无效

c - 在C标准库函数中如何确定返回char指针是否需要空闲?