我只是不知道有关容器类的动态数组这里是我如何做的一个例子。
容器类:
class Container{
private:
int n, current;
Class *C;
public:
Container(): C(NULL), n(0), current(0){}
void expandC(int ammount){
Class *NewClass= new Class[ammount];
for (int i = 0; i < n; i++)
NewClass[i] = C[i];
delete []C;
C = NewClass;
n = ammount;
}
};
为什么我在delete[] C
行上收到错误?
编辑:如果抓住了三阶规则的本质,那就意味着你必须定义一个复制构造函数,一个赋值运算符或一个析构函数。在我的情况下,最重要的可能是复制构造函数。
以下是我如何理解如何在我的案例中定义它们:
Container(): C(NULL), n(0), current(0){}
Container(int N, vector<string> a){
C = new Class[N];
for(int i = 0; i<n; i++){C->setA(a[i]);}
n=N;
}
~Container(){ delete [] C;}
这是一个很好的做法,我将来会用它,但在这种情况下,我没有帮助过我。
我在评论中注意到我的错误与访问冲突有关,我在这里发布以防万一。
Unhandled exception at 0x53f0edfc (msvcr90d.dll) in dinamicTest.exe: 0xC0000005: Access violation writing location 0xabababab.
所要求的初始完整版
答案 0 :(得分:3)
您收到错误的最可能原因是您没有关注 Rule of Three 。
请注意,您的类C
中有一个指针成员Container
,此指针成员指向动态分配的内存。现在考虑代码需要创建Container
类副本的场景,因为您没有提供重载的复制构造函数,所以将使用编译器生成的隐式复制构造函数。指针成员将浅浅地复制到新创建的对象中。当发生这种情况时,多个指针的对象成员指针指向相同的动态内存,当其中一个获得delete
时,另一个成为悬空指针并导致问题。
答案 1 :(得分:0)
问题在于addC
。请考虑以下两行:
expandC(n+1);
C[n].setA(name);
此出现以增加动态分配的数组的大小,然后将值存储在数组的最后一个条目中。当然,如果数组n+1
条目大,那么最终条目将被n
索引。
但是,n
不是addC
的本地变量。 n
是该类的成员,并被设置为expandC
操作的副作用。
考虑这些带注释的行:
// n starts out as 10:
expandC(n+1); // calls expandC(11), of course
// but expandC sets n to 11!
// n is now 11
C[n].setA(name); // C has 11 entries, but n is 11: BOOM!
你可以这样解决这个问题:
void addC(string name){
expandC(n+1);
C[n-1].setA(name);
}