C - 在内存被释放()之后访问数据? [英] C - Accessing data AFTER memory has been free()ed?

查看:12
本文介绍了C - 在内存被释放()之后访问数据?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm reading a lot about malloc() and free() in Standard C. As I understand it, you malloc() for some memory exactly once and then you free() that same memory exactly once. It may be bad practice, but I understand that after you malloc() memory, you can define multiple pointers to it. And once you free() any of those pointers, the allocated memory is de-allocated?

考虑这个玩具示例:

#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
", *p, *q);              // Everything's ok so far...
    free(p);                                        // free() my allocated memory?
    sleep(10);                                      // wait
    printf("%c
", *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) 我写在这块内存中的还是那里"的,这就是为什么我可以通过第二个指针访问它们?

So I assume that when I free() the first pointer, the memory is considered free()ed, but the data value(s) I wrote in this block of memory are still "there", which is why I can access them via the second pointer?

(我不是说这是个好主意,我是想了解系统的逻辑.)

(I'm not proposing that this is a good idea, I'm trying to understand the logic of the system.)

推荐答案

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

When you malloc memory, you're given a pointer to some space, and when you free it, you're giving it back to the system. Often, you can still access this memory, but using memory after you have freed it is VERY BAD.

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

The exact behavior is undefined, but on most systems you can either continue to access the memory, or you get a segfault.

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

One interesting experiment you can try is to try and malloc more memory after you free'd that pointer. On most systems I've tried, you get the same block back (which is a problem, if you were relying on the data being there in the freed block). Your program would end up using both pointers, but since they point to the same physical data, you'll be overwriting your own data!

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

The reason for this is that when you malloc data (depending on the malloc implementation of course), malloc first requests a block of data from the operating system (typically much larger than the malloc request), and malloc will give you a segment of that memory. You'll be able to access any part of the memory malloc originally got from the operating system though, since to the operating system, it's all memory your program is internally using. When you make a free, you're telling the malloc system that the memory is free, and can be given back to the program later on.

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

Writing outside of the malloc area is very dangerous because

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

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

If you are interested in learning more, I would recommend running your program through valgrind, a leak detector, to get a better picture of what's freed/not freed.

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

PS: On systems without an OS, you most likely wont get a segfault at all, and you'll be able to wite anywhere willy nilly. The OS is responsible for triggering a segfault (when you write/read to memory you don't have access to, like kernel or protected memory)

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

If you are interested in learning more, you should try to write your own malloc, and/or read/learn about the memory management operating systems do.

这篇关于C - 在内存被释放()之后访问数据?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆