C++ 本地声明的对象';内部内存是否在范围外完好无损?
函数C++ 本地声明的对象';内部内存是否在范围外完好无损?,c++,pointers,scope,C++,Pointers,Scope,函数f1创建foo的实例,并设置foo.ptr[0]=2 #include <iostream> using namespace std; class foo { public: int *ptr; inline foo(int a) { ptr = new int[a]; } inline ~foo() { delete[] ptr; }
f1
创建foo
的实例,并设置foo.ptr[0]=2
#include <iostream>
using namespace std;
class foo {
public:
int *ptr;
inline foo(int a) {
ptr = new int[a];
}
inline ~foo() {
delete[] ptr;
}
};
foo f1() {
foo a(5);
a.ptr[0] = 2;
return a;
}
int main() {
foo a = f1();
cout<<a.ptr[0]<<endl;
return 0;
}
#包括
使用名称空间std;
福班{
公众:
int*ptr;
内联foo(inta){
ptr=新整数[a];
}
内联~foo(){
删除[]ptr;
}
};
foo f1(){
fooa(5);
a、 ptr[0]=2;
返回a;
}
int main(){
foo a=f1();
标准从来没有说你应该期望一个“垃圾值”。相反,它说你会得到未定义的行为。因为你没有遵循三(或五)的规则,当f1
返回时,动态分配的int
s数组将被销毁,对象a
将以指向已销毁数组的指针结束。若要访问此数组,将出现未定义的行为
您可能看到值2
的原因是,自从值2在内存中以来,该内存位置没有被重用。但是,就标准而言,对此进行推理是毫无意义的。标准从来没有说您应该期望“垃圾值”。相反,它表示您将获得未定义的行为。由于您没有遵循三(或五)规则,因此当f1
返回时,动态分配的int
s数组将被销毁,并且对象a
以指向已销毁数组的指针结束。要访问该数组,您将获得未定义的行为
您可能看到值2
的原因是,自从值2出现在内存位置后,该内存位置就没有被重用。但是,就标准而言,对此进行推理是毫无意义的。这是未定义的行为。您正在调用delete[]
在一个已经释放的内存位置上。你的期望相当于依赖一个已定义的结果,没有这样的野兽有未定义的行为。要了解所有这些对未定义行为的引用到底意味着什么,@chris,已经释放的内存位置?我想,每当一个对象超出范围,它就是析构函数ts调用。现在,这里的析构函数使用delete
释放分配给ptr
的内存。对吗?@learner,是的,函数中的对象被销毁,内存被释放。然后,在main
中有一个a
的理论副本,因此返回的一个可能也会被销毁,然后是main被销毁。它们都共享同一个指针,并且只有一个new[]
@learner,函数返回一个临时值,主值是由它构造的副本,临时值被销毁。不过编译器可以选择删除该副本。这是未定义的行为。您正在调用delete[]
在一个已经释放的内存位置上。你的期望相当于依赖一个已定义的结果,没有这样的野兽有未定义的行为。要了解所有这些对未定义行为的引用到底意味着什么,@chris,已经释放的内存位置?我想,每当一个对象超出范围,它就是析构函数ts调用。现在,这里的析构函数使用delete
释放分配给ptr
的内存。对吗?@learner,是的,函数中的对象被销毁,内存被释放。然后,在main
中有一个a
的理论副本,因此返回的一个可能也会被销毁,然后是main被销毁。它们都共享同一个指针,并且只有一个new[]
@learner,函数返回一个临时值,主值是由它构造的副本,临时值被销毁。不过,编译器可以选择删除该副本。