gpt4 book ai didi

C - 在内存被释放()之后访问数据?

转载 作者:行者123 更新时间:2023-12-03 16:15:14 24 4
gpt4 key购买 nike

我在标准 C 中阅读了很多关于 malloc() 和 free() 的内容。据我所知,您 malloc()只需要一次内存,然后你 free()相同的内存恰好一次。这可能是不好的做法,但我明白在你之后 malloc()内存,你可以定义多个指向它的指针。一旦你free()任何这些指针,分配的内存被取消分配?

考虑这个玩具示例:

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

int main(){

char* p = (char*)malloc(10 * sizeof(char)); // allocate memory
int* q = (int*)p; // pointer to the same block of memory
*p = 'A'; // Input some data
printf("TEST:: %c %d\n", *p, *q); // Everything's ok so far...
free(p); // free() my allocated memory?
sleep(10); // wait
printf("%c\n", *q); // q now points to de-allocated memory
// shouldn't this segfault?

free(q); // *** SEGFAULTS HERE ***

return 0;
}

输出是:
[Linux]$ ./a.out
TEST:: A 65

*** Error in `./a.out': double free or corruption (fasttop): 0x0000000001ac4010 ***
======= Backtrace: =========
...lots of backtrack info...

所以我假设当我 free()第一个指针,内存被认为是 free() ed,但 数据值我写的这块内存仍然“存在”,这就是为什么我可以通过第二个指针访问它们?

(我不是建议这是一个好主意,我试图理解系统的逻辑。)

最佳答案

当你 malloc 内存时,你会得到一个指向某个空间的指针,当你释放它时,你将它归还给系统。通常,您仍然可以访问此内存,但是在释放内存后使用它是非常糟糕的。

确切的行为未定义,但在大多数系统上,您可以继续访问内存,或者出现段错误。

您可以尝试的一项有趣实验是在释放该指针后尝试分配更多内存。在我尝试过的大多数系统上,你会得到相同的块(这是一个问题,如果你依赖于释放块中的数据)。您的程序最终会使用这两个指针,但由于它们指向相同的物理数据,您将覆盖自己的数据!

这样做的原因是,当你 malloc 数据时(当然取决于 malloc 的实现),malloc 首先从操作系统请求一个数据块(通常比 malloc 请求大得多),malloc 会给你其中的一部分内存。不过,您将能够访问最初从操作系统获得的内存 malloc 的任何部分,因为对于操作系统而言,它是您的程序在内部使用的所有内存。当您释放时,您是在告诉 malloc 系统该内存是空闲的,并且可以稍后返回给程序。

在 malloc 区域外写是很危险的,因为

  • 它可能会出现段错误,具体取决于您的 c 实现
  • 您可以覆盖 malloc 所依赖的元数据结构,当您稍后在
  • 上释放/malloc 更多数据时,这会导致非常糟糕的问题。

    如果您有兴趣了解更多信息,我建议您通过泄漏检测器 valgrind 运行您的程序,以更好地了解已释放/未释放的内容。

    PS:在没有操作系统的系统上,您很可能根本不会遇到段错误,并且您可以在任何地方随意使用。操作系统负责触发段错误(当您写入/读取您无权访问的内存时,例如内核或 protected 内存)

    如果您有兴趣了解更多信息,您应该尝试编写自己的 malloc,和/或阅读/了解内存管理操作系统所做的工作。

    关于C - 在内存被释放()之后访问数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42588482/

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