如何通过带有指向基类的指针的删除运算符释放内存
How is memory deallocated by delete operator with pointer to base class
请考虑以下代码:
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
将如何释放内存?
我是指针和内存管理的新手,所以我更喜欢描述性答案。谢谢
您的代码具有未定义的行为。
可以使用
base* ptr = new derived();
delete ptr;
但是不能使用
base* ptr = new derived[10];
delete [] ptr;
以下是 C++11 标准中的相关文本(强调我的(:
在第一种替代方法(删除对象(中,如果要删除的对象的静态类型与其动态类型不同,则静态类型应是要删除的对象的动态类型的基类,并且静态类型应具有虚拟析构函数或行为未定义。在第二种备选方案(删除数组(中,如果要删除的对象的动态类型与其静态类型不同,则行为未定义。
正如其他人已经注意到的那样,这是:
base* dis=new derived[50];
delete[] dis;
是未定义的行为。例如,阅读这个问题以了解原因:为什么通过基指针delete[]
派生对象数组是未定义的行为?
作为解决方案,我建议使用唯一指针的向量:
struct Base { virtual ~Base() = default; };
struct Derived : Base {
Derived() { std::cout << "Derived constructed...n"; }
~Derived() { std::cout << "Derived destroyed...n"; }
};
int main() {
std::vector<std::unique_ptr<Base>> v;
std::generate_n(std::back_inserter(v), 50,
[]{ return std::make_unique<Derived>(); });
}
现场演示:https://wandbox.org/permlink/jcG71bDb1U7wsp2T。
当然,在这种情况下,Derived
对象不会放置在连续的内存块中。
相关文章:
- 使用函数引用指向节点的指针删除链表中的节点?
- 如何通过指向元组的共享指针删除对象
- 函数内的 C++ 指针删除
- 一个对象的两个指针.删除了一个指针,对象仍然存在
- 如何通过存储在 std::list 中的指针删除对象?
- C++中的智能指针删除
- 将C 中的每个指针删除作为阵列的指针安全吗?
- 使用 C 字符串和指针.删除除小写和空格以外的任何字符
- 在特定情况下,指针删除和铸造之间的关系不清楚
- 提升属性树:使用指向节点及其父节点的指针删除节点
- 警告C4150在尝试包装本机C 类时,指向不完整类型的指针删除
- C++ Valgrind 双指针删除,用于防止内存泄漏
- C 通过指向其基类的指针删除派生对象
- 将指针删除到数组
- 当通过其中一个指针删除对象时,C++将所有指针设置为null
- 智能指针删除器和"using"名称为"pointer"关键字
- 通过指向其基的指针删除 POD 对象是否安全
- 模板化的出列无效指针:删除类时失败
- 使用"this"指针删除
- (C++) list.error 方法和使用指针删除内存