C++ C++;堆上的作用域

C++ C++;堆上的作用域,c++,scope,heap,heap-memory,C++,Scope,Heap,Heap Memory,为什么我在删除其作用域后将其输出为10?我创建了一个类a,它有一个指针类型的成员变量,另一个类B有另一个成员变量x。现在我在堆上为B分配内存,值为10为x。为了创建类A的实例,我使用了x的内存地址。现在我正在删除对象b并打印类A的指针ref的值。 我得到了为什么我得到的输出是10,因为我们可以看到保存该值的内存不再在堆上持久化了 #include<iostream> using namespace std; class A { public: int *ref;

为什么我在删除其作用域后将其输出为10?我创建了一个类a,它有一个指针类型的成员变量,另一个类B有另一个成员变量x。现在我在堆上为B分配内存,值为10x。为了创建类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; 
}
#包括
使用名称空间std;
甲级
{    
公众:
int*ref;
A(int*ref):ref(ref)
{
}
};
B类{
公众:
int x;
B(intx):x(x){}
};
int main()
{
B*B=新的B(10);
A&b->x;
删除b;

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

如果您试图访问无效内存,则无法保证会发生什么情况。可能发生的情况是,它无论如何都会访问无效内存,如果该内存没有更改,您可能会得到旧的值。这实际上是一件坏事,因为程序似乎按预期工作,而实际上并非如此

我得到了为什么我得到的输出为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; 
}

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

这是未定义的行为。举个例子,当我在MSVC中运行示例时,我的输出是
-66572237

如果您试图访问无效内存,则无法保证会发生什么情况。可能发生的情况是,它无论如何都会访问无效内存,如果该内存没有更改,您可能会得到旧的值。这实际上是一件坏事,因为程序似乎按预期工作,而实际上并非如此

我得到了为什么我得到的输出为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; 
}

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

您所拥有的是未定义的行为,因为程序正在访问不再属于它的内存。

delete
释放内存以便重用,但这并不意味着该内存位置中的值被设置为零(如果这是您期望的值)。

由于程序正在访问不再属于它的内存,因此您所拥有的行为是未定义的。

delete
释放内存以便可以重用,但这并不意味着该内存位置中的值设置为零(如果这是您期望的值).

这是由于悬空指针效应。虽然我们已经删除了内存数据,但这些数据尚未被擦除,或者其他数据没有存储在那里,而且我们的指针仍然指向该内存

供参考

这是由于悬空指针效应。虽然我们已经删除了内存数据,但这些数据还没有被擦除,或者其他数据没有被存储在那里,我们的指针仍然指向该内存

供参考

PC中几乎所有的删除操作都不删除资源,只释放它们占用的空间供将来使用。因此,数据可能仍存在一定时间,但访问该数据的结果尚未定义。主题外,但您使用的术语范围是错误的。范围指源代码中名称是可见的。它不引用变量的生存期,通常称为区段。因此,在堆上分配的数据具有不确定的区段(因为它的生存期直到您删除它)但是任何指向该数据的指针变量都有正常的作用域规则。PC中几乎所有的删除操作都不删除资源,而只是释放它们所占用的空间以供将来使用。因此,数据可能仍然存在一段时间,但访问该数据的结果未定义。脱离主题,但您使用的是术语s以错误的方式处理。作用域指的是源代码中名称可见的部分。它不指变量的生存期,通常称为范围。因此,堆上分配的数据具有不确定的范围(因为它在删除它之前一直存在),但指向该数据的任何指针变量都具有正常的作用域规则。