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

查看:215
本文介绍了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\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,但是我在这里写的 数据值 内存块仍然存在",这就是为什么我可以通过第二个指针访问它们?

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.)

推荐答案

在分配内存时,将为您提供指向某个空间的指针,在释放内存时,会将其返回给系统.通常,您仍然可以访问此内存,但是释放内存后使用内存会非常不便.

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天全站免登陆