堆上的C ++范围

时间:2019-01-04 07:45:40

标签: c++ scope heap heap-memory

为什么删除范围后为什么输出为 10 ?我创建了一个具有指针类型成员变量的类 A 和另一个具有另一个成员变量 x 的类B。现在,我在B的堆上为 x 分配了值 10 的内存。要创建类 A 的实例,我使用了 x 的内存地址。现在,我删除对象b并打印类 A 的指针 ref 的值。    我明白为什么我得到的输出为 10 了,因为我们可以看到拥有该值的内存不再保留在堆上了?

#include<iostream>
using namespace std;

class A
{    
   public:
   int *ref;
   A(int *ref):ref(ref)
   {
   }
};

class B{
   public:
   int x;
   B(int x):x(x){}
};

int main()
{
   B *b=new B(10);
   A a(&b->x);
   delete b;
   cout<<*a.ref<<endl; 
}

3 个答案:

答案 0 :(得分:4)

这是未定义的行为。举例来说,当我在MSVC中运行您的示例时,我的输出为-572662307

如果您尝试访问无效的内存,将无法保证会发生什么。可能发生的情况是它仍然访问无效的内存,并且如果该内存没有更改,您可能会得到旧值。这实际上是一件坏事,因为看起来程序正在按预期运行,而实际上却并非如此。

  

我明白了为什么我看到输出是10   保持该值不再保留在堆上?

该内存不再有效,但是数字10可能仍在该内存中,并且a.ref仍指向该内存。因此,即使内存无效,10可能仍然会保留。

答案 1 :(得分:0)

您所拥有的是未定义的行为,因为该程序正在访问不属于它的内存。
!apt-get install -y -qq software-properties-common python-software- properties module-init-tools !add-apt-repository -y ppa:alessandro-strada/ppa 2>&1 > /dev/null !apt-get update -qq 2>&1 > /dev/null !apt-get -y install -qq google-drive-ocamlfuse fuse from google.colab import auth auth.authenticate_user() from oauth2client.client import GoogleCredentials creds = GoogleCredentials.get_application_default() import getpass !google-drive-ocamlfuse -headless -id={creds.client_id} -secret= {creds.client_secret} < /dev/null 2>&1 | grep URL vcode = getpass.getpass() !echo {vcode} | google-drive-ocamlfuse -headless -id={creds.client_id} - secret={creds.client_secret} !mkdir -p drive !google-drive-ocamlfuse drive 释放了内存以便可以重复使用,但这并不意味着该内存位置中的值设置为零(如果这是您期望的值)。

答案 2 :(得分:0)

这是由于悬空指针效应。尽管我们已经删除了内存数据,但尚未删除该内存数据,或者尚未在该数据上存储其他数据,并且我们的指针仍指向该内存。

供参考 https://www.geeksforgeeks.org/dangling-void-null-wild-pointers/