gpt4 book ai didi

在 C 中调用 free()

转载 作者:行者123 更新时间:2023-12-02 07:37:19 24 4
gpt4 key购买 nike

当我调用 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/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com