【问题标题】:Can you delete dynamically allocated memory from a separate program?您可以从单独的程序中删除动态分配的内存吗?
【发布时间】:2019-10-11 15:06:53
【问题描述】:

这个问题纯粹是出于好奇。我最近了解到,如果在 Heap 中动态分配内存空间,那么删除内存空间非常重要。我的问题是,如果内存空间的地址已知,是否可以使用不同的 C++ 程序(从创建内存空间的程序)删除动态分配的内存空间?

这是一个例子:

CODE01.CPP

#include <iostream>
using namespace std;

int main() {
    int *a = new int;
    cout << a;
    int foo;
    cin >> foo;  // for blocking the program from closing.
    return 0;
}

CODE01.CPP 的输出(比如)

0x7c1640

CODE02.CPP

#include <iostream>
using namespace std;

int main() {
    int *a = (int*)0x7c1640;
    delete a;
    return 0;
}

这行得通吗?如果我先运行code01.cpp,然后立即运行code02.cpp,堆中的内存会被删除吗?

【问题讨论】:

  • 明确一点,在CODE01中,程序结束时内存会被清空。如果您的对象有析构函数,它可能无法正确清理。但在这种情况下,您处理的是int,所以没关系。如果您关心内存,分配的内存总是在程序结束时释放。
  • 那你学错了。一旦程序终止,所有内存都会交还给操作系统
  • 现代操作系统将为每个进程提供单独的虚拟地址空间。这些地址在进程之间毫无意义。
  • @MarekR 我不明白为什么这太宽泛了?只需回答说明内存空间未共享即可。这是个好问题。
  • 常见的现代桌面平台不支持此功能。有一些旧平台(今天不常用)可以做到这一点(例如,具有操作系统分配内存块的旧 Amiga,具有协作内存块管理的旧 Mac)。可能有现代嵌入式平台也可能提供该功能(可执行覆盖和共享内存池)。

标签: c++ memory-management virtual-address-space


【解决方案1】:

任何现代操作系统都会为这两个程序创建一个单独的虚拟地址空间。因此,您在code01.cpp 中打印的地址仅与该程序相关,您无法从code02.cpp 访问地址空间。

所以回答您的直接问题:运行cpp02.cpp 不会以任何方式影响仍在运行的cpp01.cpp 的状态。

【讨论】:

    【解决方案2】:

    分配给操作系统的工作之一是确保一个进程不会损害另一个进程。这意味着防止一个进程以任何方式直接影响另一个进程使用的内存。

    有几种机制可以做到这一点,但它们都破坏了这个想法

    “如果我知道 that 进程中使用的指针的值,那么我可以从 this 进程中对其内存做一些事情。”

    因为这正是操作系统应该防止


    也就是说,许多操作系统提供了特殊的通道(用于进程间通信),您可以滥用这些通道来允许类似的事情。但你必须努力,细节取决于操作系统。

    【讨论】:

    • 即使您能够绕过操作系统内存保护,这两个进程仍将使用自己的 C++ 堆和自己的控制结构。释放到错误的进程堆将是一场灾难。
    • 为了让它工作,你必须从语言的新/删除机制中实现你自己的“堆”管理分离。假设两个进程内存映射一个公共文件,然后将内存用于对象存储。在那种情况下,“指针”是文件偏移量。正如我所说,你必须努力,但在这种情况下,你可以让进程 B 负责释放进程 A 插入的对象。
    【解决方案3】:

    在大多数现代操作系统上,简短的回答是否定的。 大多数操作系统使用virtual memory,这意味着程序A中的0x7c1640不一定是程序B中的0x7c1640。为了实现这一点,您必须为此编写一个没有内存保护的自定义操作系统,此时任何程序都可以覆盖任何其他程序,这是一个重大的安全漏洞。

    related question 提供了下图,说明了虚拟地址是如何被占用的。每个程序都会得到一个操作系统翻译的假内存地址,因此每个程序都会得到一个不同的堆,并且不能直接通过内存相互交互,至少在一个通用的虚拟内存系统上是这样。

    【讨论】:

      猜你喜欢
      • 2011-09-06
      • 2013-12-27
      • 2011-06-17
      • 2018-05-26
      • 2017-11-28
      • 1970-01-01
      • 2014-01-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多