gpt4 book ai didi

C - 内存被释放后访问数据?

转载 作者:行者123 更新时间:2023-11-30 16:06:21 25 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,但是数据值( s)我在这 block 内存中写的仍然“在那里”,这就是为什么我可以通过第二个指针访问它们?

(我并不是说这是一个好主意,我只是想理解系统的逻辑。)

最佳答案

当您分配内存时,您将获得一个指向某个空间的指针,当您释放它时,您将其返回给系统。通常,您仍然可以访问该内存,但在释放内存后使用它是非常糟糕的。

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

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

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

在 malloc 区域之外写入是非常危险的,因为

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

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

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

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

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

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