【发布时间】:2019-09-06 05:26:58
【问题描述】:
考虑这段代码:
class base{
T* obj=new T[40];
//...
public:
base(){/*...*/}
virtual ~base(){
delete[] obj;
//...
}
...
};
class derived : public base{
T* obj2=new T[20];
//...
public:
derived(){/*...*/}
~derived(){
delete[] obj2;
//...
}
...
};
void func(){
base&& exmp=giveder(); //giveder() returns derived
base* dis=new derived[50];
//...
delete[] dis;
}
在上面的代码中,exmp 将被正确地破坏,因为析构函数被声明为虚拟的。但我的问题是dis 指向的免费存储是否会按预期释放,如果是,那么如何释放?
很明显sizeof(base) 和sizeof(derived) 是不同的。但这不会与exmp 混淆,但它会与dis 混淆吗?我认为它不起作用,因为无法从指向基址的指针中找出sizeof(derived),因此它无法确定需要释放多少字节。虽然我真的很想知道语言规范以及它是否合法。如果这是合法的,那么释放正在获取的东西的解决方法是什么?
一个附带的问题,数组不知道自己的大小(对吗?),那么析构函数中的delete[] obj 和delete[] obj2 将如何释放内存?
我是指针和内存管理的新手,所以我更喜欢描述性的答案。谢谢
【问题讨论】:
-
所有数组的内存都会被正确释放。
new[]存储delete[]在释放内存时使用的簿记信息。无论对象在自动内存还是动态内存中,虚拟析构函数都被正确调用,并且在析构函数被调用后释放正确的字节数 -
@RemyLebeau,OP 的代码具有未定义的行为。
-
为什么在你的类原型而不是构造函数中分配内存?
-
数组不知道自己的大小,但内存管理器知道,因为它把那个大小存储在一个特殊的地方。
-
@SPlatten 如果它是真正的代码,那么我真的会在构造函数中分配内存(当然我可能希望用户将大小作为参数)
标签: c++ inheritance dynamic-dispatch