【问题标题】:Get value of non-deleted pointer获取未删除指针的值
【发布时间】:2013-02-05 20:16:36
【问题描述】:

我正在学习OOP,遇到了这个问题:

如果我们这样做:

A* a = new A;

new 运算符从堆中为变量 a 找到一个空间。我想知道那个变量所在的地址。

问题 1

那个地址是哪一个?这两者有什么区别?

cout <<  a;
cout << &a;

问题2(主要)

假设我 delete 指针。程序退出。只要指针没有被类的析构函数破坏,当我再次运行程序时,我可以使用它的地址(例如 0x0035fa24)取回该对象吗?如果是,怎么做?

【问题讨论】:

  • Q1:第一个。 Q2:不是。程序的另一个实例只是另一个进程,每个进程的地址空间是分开的。您的对象已泄漏,并且消失了。永远。

标签: c++ oop pointers heap-memory


【解决方案1】:

问题 1

那个地址是哪一个?这两者有什么区别?

a对象的地址。 &amp;a指针的地址。

问题2(主要)

假设我没有删除指针。程序退出。只要 由于指针没有被类的析构函数破坏,我可以 当我运行 再编程?如果是,怎么做?

典型的现代操作系统不允许您这样做。当第一个进程退出时,它将回收内存。不允许任何后续启动的进程查看第一个进程的内存内容,因为这会带来重大的安全风险。

【讨论】:

  • 如果我没记错的话 - 至少在 Windows 的情况下 - 在进程退出后,它获得的所有资源将被归还(内存、句柄等)。其次,每个进程都将获得一个新的虚拟地址空间,因此读取先前由另一个进程分配的内存的可能性几乎为零,并且基本上“不可能”确定性地检查映射到虚拟地址的物理地址。
  • @RedXIII:事实上,现代安全操作系统会竭尽全力确保不会给任何进程提供仍然包含其他进程剩余数据的内存页面。如果页面在重用时没有被擦除,这将是一个重大的安全漏洞。
  • 这是否意味着每次进程释放一个页面时,内存页面被清除为0s/1s?
【解决方案2】:

第一季度:

new 运算符从堆中为变量 a 找到一个空间

不,它没有。 new 运算符创建A 类型的对象。然后使用该地址初始化变量a

所以,a 计算为对象所在的地址。

&amp;a 计算为变量 a 的地址。

第二季度: 从技术上讲,该行为是未定义的(您将取消引用指向不存在的对象的指针)。实际上,答案是“不”。当您退出时,操作系统将释放您进程的所有内存。

【讨论】:

  • 我不认为在程序结束之前不销毁所有对象是 UB,只是从程序员的角度来看很可能是不正确的。
  • 关于内存泄漏的 UB。我只是重新阅读了标准的相关部分。我可能是错的。虽然在后续运行中使用该指针仍然是UB。
【解决方案3】:

问题一:

您的变量a 是一个指针。取&amp;a 给出的是指针本身的地址,而不是存储class A 实例的地址。

问题 2:

不,你不能那样做。机器不会为您维护一些“如果 A 的所有实例的列表”,除非您自己维护这样的列表。

【讨论】:

    【解决方案4】:

    答案 1:a 将是地址。 &amp; 运算符返回您稍后写入的地址。简单来说,&amp;a 会给你一个指针的地址,a 是变量a 存储的地址,*aa 指向的地址的内容。

    至于2,我认为理论上可行,但实际上不可能。

    【讨论】:

      【解决方案5】:
      A* a = new A;
      cout <<  a;
      cout << &a;
      

      在上面的代码sn-p中,你在堆上创建了一个新的A,它的地址被分配给了a。然后打印出 a 的值,这是动态创建的对象的地址。然后打印出指针本身的地址(在堆栈上)。

      不,你绝对不能在会话之间恢复丢失的记忆。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2010-09-08
        • 1970-01-01
        • 2013-06-01
        • 2015-08-09
        • 1970-01-01
        • 2018-01-23
        • 2013-01-03
        相关资源
        最近更新 更多