内存泄漏,访问释放内存和双重免费之间有什么区别

What is the difference between memory leak, accessing freed memory and double free?

本文关键字:内存 免费 之间 区别 什么 泄漏 访问 释放      更新时间:2023-10-16

我试图弄清楚与内存模型相关的三种问题之间有什么区别。

如果我想模拟memory leak方案,我可以创建一个指针而无需调用相应的删除方法。

int main() {
    // OK
    int * p = new int;
    delete p; 
    // Memory leak
    int * q = new int;
    // no delete
}

如果我想模拟double free方案,我可以两次释放指针,此部分内存将在两次分配。

a = malloc(10);     // 0xa04010
b = malloc(10);     // 0xa04030
c = malloc(10);     // 0xa04050
free(a);
free(b);  // To bypass "double free or corruption (fasttop)" check
free(a);  // Double Free !!
d = malloc(10);     // 0xa04010
e = malloc(10);     // 0xa04030
f = malloc(10);     // 0xa04010   - Same as 'd' !

但是,我不知道什么是accessing freed memory。有人可以给我一个 accessing freed memory的例子?

  1. 内存泄漏不好。
  2. 双释放更糟。
  3. 访问释放的内存是 walser

内存泄漏

这不是错误。泄漏程序有效。这可能不是问题。但这仍然很糟糕。随着时间的流逝,您的程序将从主机中保留内存,并且永远不会发布。如果主机的内存在程序完成之前已满,您会遇到麻烦。

双释放

根据标准,这是不确定的行为。实际上,这几乎总是由C 运行时呼叫std::abort()

访问释放的内存

也未定义的行为。但是在某些情况下,不会发生任何不好的事情。您将测试您的程序,将其投入生产。有一天,出于明显的原因,它会破裂。它将艰难地打破:随机。重新制作简历的最佳时间。

这是如何访问释放内存的方法:

// dont do this at home
int* n = new int{};
delete n;
std::cout << *n << "n"; // UNDEFINED BEHAVIOUR. DONT.

您的内存泄漏示例(分配内存但释放它)和双重(将指针传递给分配的内存到free/delete不止一次)是正确的。

执行双重的并不意味着您的示例指示的malloc将返回一部分内存的一部分。它要做的是调用不确定的行为,这意味着无法预测程序的行为。

访问自由的内存意味着释放指针,然后随后尝试使用它:

int *a = malloc(10 * sizeof(int));     // allocate memory
free(a);                               // free memory
print("a[0]=%dn", a[0]);              // illegal: use after free

您对使内存泄漏和双重漏洞是正确的。当您放弃已释放的指针时,就会发生释放记忆:

int *ptr = malloc(sizeof(int));
*ptr = 123;
free(ptr);
int invalid = *ptr; // Accessing freed memory

这样的问题很难检测到,因为该程序在一段时间内继续按预期工作。如果您期望在以后的某个时间重复使用指针变量,则在调用free后立即分配NULL是一个好主意。这样,随后的退解会失败。

我试图弄清楚与内存模型相关的三种问题之间有什么区别。

  • 内存泄漏 - 您动态分配内存,永远不会发布。

  • 双免费 - 您动态分配内存并多次发布

  • 免费后访问 - 您动态分配内存,然后在版本后释放和访问该内存。