【问题标题】:How are we able to access the pointer after deallocating the memory?释放内存后如何访问指针?
【发布时间】:2014-03-28 20:01:40
【问题描述】:

据我了解

free() 用于释放我们之前使用 malloc 分配的内存。

在接下来的 sn-p 中,我释放了我分配的内存。但是即使在释放之后我也能够访问指针?怎么可能?

免费在内部如何运作?

#include<iostream>
using namespace std;

int main()
{
   int *p=(int *)malloc(sizeof(int));
   *p=17;
   free(p);
   *p=*p+1;
   printf("\n After freeing memory :: %d ",*p );
   return 0;
}

【问题讨论】:

  • 内存还在,通常不会立即被覆盖。但是,将来对 malloc 的调用最终会重新使用该内存。
  • 您可以调用同样未定义的行为,方法是从不分配内存并简单地取消引用不确定的指针。在您的代码中,一旦调用 free(),指针中包含的地址的有效性就会丢失,因此即使对其进行评估,更不用说取消引用,也会调用未定义的行为。

标签: c pointers malloc free


【解决方案1】:

您当然可以在拨打free(p) 之后继续使用p,没有什么能阻止您。然而,结果将是完全不确定和不可预测的。它只能靠运气。这是一个称为“use after free”的常见编程错误,它在许多程序中运行了,没有“问题”——直到它引起问题。

有些工具非常擅长发现此类错误,例如Valgrind

【讨论】:

  • 太棒了!是的,你是对的,这是 c 中未定义的行为之一。
  • 杰里米,你的回答没有解释免费在内部是如何工作的。
  • @Samveen 是的,我基本上认为问题的一部分有点反问,因为谷歌搜索“免费工作如何”会产生无数资源。
【解决方案2】:

访问dangling pointer 将导致未定义的行为。 悬空指针是已经被释放的指针。

【讨论】:

  • 您的回答并没有解释 free 在内部是如何工作的,只是语言规范承担了不应该做的事情。
  • 也更新你的答案(在关闭的情况下它被标记)
【解决方案3】:

free(p) 之后,p 是一个悬空指针,它不指向任何地方。 free() 只是释放malloc() 分配的内存块,它不会改变指向该进程地址空间中堆的指针的值。在某些平台上,如果您在释放后尝试取消引用指针,您可能会遇到段错误。如果在释放后将指针p 分配给NULL,这是一种很好的做法。

【讨论】:

  • "如果在释放后将指针 p 分配给 NULL,这是一种很好的做法。" - 每个人都应该做的非常好的练习
  • 您的回答并没有解释 free 在内部是如何工作的,只是语言规范承担了不应该做的事情。
【解决方案4】:

在大多数系统和标准库中,malloc 通过从操作系统分配比所需更大的内存块(在某些系统上高达 64K)进行优化,然后根据需求从该池中在内部分配。这同样适用于释放(free),因为free'd 内存没有被释放,而是放回内存池中,以防另一个请求进来,在这种情况下,池是重复使用。

因此,对free 的调用实际上并未从进程的地址空间中释放内存,因此即使在释放后仍可访问。

我对这样做的原因的理解是系统调用很昂贵,因此对malloc 的初始调用将进行系统调用以获得足够的内存,以便将来对malloc 的请求不会立即触发另一个系统调用以获取更多内存记忆。

进一步阅读请看this page on WikipediaHow do malloc() and free() work?How is malloc() implemented internally?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-03-13
    • 2013-06-30
    • 2022-09-27
    • 1970-01-01
    • 2020-06-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多