删除一个对象数组,该数组被上推为基指针
Deleting an array of objects upcasted to base pointers
开始将一些库从msvc移到mingw,并且发现当想要删除一个数组的更新对象时,msvc的行为非常有趣。也就是说,msvc做了一些黑魔法(它似乎喜欢这样做),下面的代码执行得很好,但是在mingw(4.7.2)(崩溃)。我相信mingw的运行是正确的,这是msvc的巫术,这是产生潜伏bug的问题。
代码:#include <iostream>
class foo{
static int idgen;
protected:
int id;
public:
foo(){
id = idgen++;
std::cout << "Hello ( foo - "<<id<<")"<<std::endl;
}
virtual ~foo(){
std::cout << "Bye bye ( foo - "<<id<<")"<<std::endl;
};
};
int foo::idgen = 0;
class bar: public foo{
double some_data[20];
public:
bar(){
std::cout << "Hello ( bar - "<<id<<")"<<std::endl;
}
~bar(){
std::cout << "Bye bye ( bar - "<<id<<")"<<std::endl;
}
};
int main()
{
const unsigned int size = 2;
foo** arr = new foo*[size];
{
bar* tmp = new bar[size];
for(int i=0; i<size; i++)
{
arr[i] = &(tmp[i]); //take address of each object
}
}
delete [] arr[0]; //take address of first object, pointer is same as tmp. This also crashes mingw
delete [] arr;
}
msvc 2010输出
Hello ( foo - 0)
Hello ( bar - 0)
Hello ( foo - 1)
Hello ( bar - 1)
Bye bye ( bar - 1)
Bye bye ( foo - 1)
Bye bye ( bar - 0)
Bye bye ( foo - 0)
和mingw(崩溃在破坏)
Hello ( foo - 0)
Hello ( bar - 0)
Hello ( foo - 1)
Hello ( bar - 1)
我的问题是,解决这个问题的正确方法是什么?目前我想到的修补方法只是尝试向下转换到每个可能的类,并在向下转换的指针上调用delete操作:
if(dynamic_cast<bar*>(arr[0]) != 0)
delete [] dynamic_cast<bar*>(arr[0]);
除了重新设计库(不是我的),有没有更好的方法?
在标准规范第5.3.5节第3段中,关于delete
操作符:
[…在第二种选择(delete array)中,如果要删除的对象的动态类型与其静态类型不同,则行为是未定义的。
所以,在这种情况下,你不应该依赖于Visual c++的温和行为,而应该尝试为数组delete
操作符提供正确类型的指针,这基本上意味着在你的情况下动态转换。
您可以通过使用vector实例来存储逐个分配的上映射对象来避免这个问题。
gcc 4.7.2即使在这里有一个简单的例子也失败了-> ideone.com/z876QX#view_edit_box所以我们显然不能使用虚析构函数,如果它是一个数组。
const unsigned int size = 2;
foo* test = new bar[size];
delete[] test;
但是,如果您使用一个指针数组,允许您使用delete
而不是delete[]
,则可以避免使用。
http://ideone.com/NfbF3n view_edit_box
const int size = 5;
foo *test[size];
for(int i = 0; i < size; ++i)
test[i] = new bar;
for(int i = 0; i < size; ++i)
delete test[i];
相关文章:
- if数组上的随机数
- 如何在动态数组上使用搜索函数
- 为什么我的 scanf() 没有在我的数组上迭代我的 for 循环?
- 在 C++ 中的数组上使用阶乘函数
- 如果我在字符数组上使用 close() 会发生什么?
- 字符串数组上的 sizeof 运算符以 C++ 为单位给出不同的输出
- 数组上的相同逻辑会产生不同的结果
- 删除动态数组上不带方括号的内容
- 如何在使用 make_unique<T[]>() 制作的模板类型数组上使用 std::fill?
- C++:带有 "auto" 的二维数组上的嵌套 For 循环
- 如何检查二维数组上的周围数字?
- 是否可以在数组上使用const_cast来更改元素?
- <<(按位左移)在 Swift 中的数组上做什么?
- 在指向对象的指针的动态数组上插入新元素
- 用于在一维数组上嵌套循环操作的正确 openmp 指令
- 在结构数组上使用 c++ std::copy
- 使用 Qt qSort() 在数组上调用 qSort
- 模板化动态数组上的内存泄漏
- C++数组上的指针数学中的未定义行为
- 在C++中,为什么要重载"const char 数组"上的函数和包装"const char