时髦的头衔,但说实话,我想不出更好的人,对不起:(
在尝试使用指针时,我遇到了这个问题,我需要帮助理解它。基本上,我创建了一个指向对象的指针的向量。当删除向量中的指针时,我希望删除原始的ovject。他们是同一个没有?
这就是我认为我在后面的代码中创建一个动态分配的数组,然后我将指针放在一个指针向量中的数组的一半元素。类testDestructor的每个对象知道创建它的“顺序”的每一步,都会通过静态整数分配一个递增的数字。
然后我pop_back并删除向量中的所有指针。我只使用pop_back,因为我想看看它们是否被矢量类删除了,显然他们没有删除,但是如果我在那里遗漏了某些内容,那就是idk。重要的是我删除它。
现在,我期望发生的是,这也会删除数组的相应元素。应该发生这种情况,因为向量和数组元素指向内存中的相同位置。即,应该调用析构函数。
所以当我然后删除数组时,我希望只有5个元素被删除,或者发生运行时错误(我在尝试删除已经删除的指针之前就已经发生了这种情况,但是可能是一个不同的场景idk)。也就是说,我希望只有五次调用析构函数。
但是,这不是发生的事情。构造函数被调用10次,但析构函数被调用15次。我错过了什么?我错过了一个构造函数(我只知道默认构造函数和复制构造函数,还有更多),还是其他的东西?因为,在我看来,当析构函数消失时,对象就消失了。
很抱歉,如果代码太多了:
testDestructor.h:
#ifndef TESTDESTRUCTOR_H
#define TESTDESTRUCTOR_H
class testDestructor
{
public:
testDestructor();
testDestructor(const testDestructor &);
~testDestructor();
static int maxTest;
int test;
};
#endif
testDestructor.cpp:
#include "testDestructor.h"
#include <iostream>
using namespace std;
int testDestructor::maxTest = 0;
testDestructor::testDestructor()
{
test = maxTest++;
cout << "testDestructor nr " << test << " created successfully\n";
}
testDestructor::testDestructor(const testDestructor &destructorToCopy)
{
test = maxTest++;
cout<< "testDestructor nr " << test << " created successfully (using the copy constructor\n";
}
testDestructor::~testDestructor()
{
//maxTest--;
cout << "testDestructor " << test << " destroyed successfully\n";
}
main.cpp中:
#include <iostream>
#include "testDestructor.h"
#include <vector>
using namespace std;
int main()
{
cout << " creating pointer array:\n\n";
testDestructor *testPtr = new testDestructor[10];
cout << " intitiating vector\n\n";
vector<testDestructor*> testVct;
for (int i = 0; i < 5; i++)
{
cout << " pushing back vector " << i << ":\n";
testVct.push_back(testPtr + i);
cout << "testDestructor " << testVct[i]->test << " pushed back\n";
}
cout << "\n";
for (int i = 4; i >= 0; i--)
{
cout << " popping back vector " << i << ":\n";
cout << "testDestructor " << testVct[i]->test << " popped back\n";
delete testVct[i];
testVct.pop_back();
}
cout << "\n";
cout << " deleting pointer array\n\n";
delete [] testPtr;
}
答案 0 :(得分:2)
当删除向量中的指针时,我期待原始指针 也可以删除。他们是同一个没有?
不,它们不一样,你的术语“删除指针”意味着你需要重新阅读一些关于C ++指针的基本内容。
new
创建东西,并返回指向它创建的内容的指针。 delete
摧毁事物并传递指向要销毁的东西的指针。指针没有改变 - 它只是在删除后没有指向任何有用的地方。
您要做的是delete
使用new[]
创建的对象数组中的单个对象。这根本无法做到。您只能使用delete []删除整批。如果您想拥有可单独删除的对象,请使用std::vector<TestDestructor>
。
答案 1 :(得分:1)
此处的问题是,testDestructor
的前五个实例会被删除两次:一次是delete testVct[i]
,另一次是delete [] testPtr;
。
第一个delete
错误。
对象由testVct
拥有,因此只能通过delete[]
的{{1}}来执行它们的破坏。只有testVct
分配单个对象时才能delete
个。{/ p>
答案 2 :(得分:1)
运算符delete[]
将在删除数组本身之前调用数组中项目的析构函数。如果您希望手动删除阵列中的某些项目,则需要在之后将其数组索引值设置为NULL
。在同一个对象上调用析构函数两次是未定义的行为,并且希望能够为你做坏事。
答案 3 :(得分:0)
首先,让我们看看你的变量声明:
testDestructor *testPtr = new testDestructor[10];
vector<testDestructor*> testVct;
这表示testPtr是指向testDestructor类型的对象的指针,testVct是指向testDestructor类型的对象的指针的向量。
此外,您使用new运算符分配一组testDestructor对象,并在testPtr中分配第一个元素的地址。现在testPtr可以用作testDestructor 对象的数组。
请注意,您尚未为任何单个testDestructor对象分配内存。这意味着您删除任何指向数组中对象的指针都将导致未定义的行为。另一方面,允许在testPtr上使用delete []来解除分配数组。
这里的一般规则是每个删除或删除[]必须匹配新的或新的[],反之亦然。
答案 4 :(得分:0)
第一
在我的测试中,该程序将核心转储到删除testVct [i];&#39;
我的g ++版本是4.1.6
也许你可以初始化testPtr:
testDestructor *testPtr[10];
for(int i=0;i<10;i++)
testPtr[i] = new testDestructor;
第二
你删除指针两次 1)删除testVct [i]; 2)删除[] testPtr;