我已经将我的问题缩小到将2个对象(包含指针数据成员)传递给一个简单的void函数。该函数返回clean,但是当main()尝试退出时,它无法回收2个对象中的第一个。下面是一段显示问题的示例代码 - 以及用于显示对象在构造,传递和销毁时的地址的print语句。
如果我只调用“print1” - 程序运行正常。但是,如果我调用“printboth” - 则无法释放对象“myNumbers”。我还可以通过删除析构函数语句来消除错误:
delete [] number;
但我认为这不是一个好主意。
有人有什么想法吗?
class dummy
{
public:
dummy() {
number = new int[1];
currentPos = -1;
std::cout<<"default constructor called for "<<this<<std::endl;
}
dummy(int len) {
number = new int[len];
currentPos = -1;
std::cout<<"parameterized constructor called for "<<this<<std::endl;
}
~dummy() {
cout<<"Calling destructor for "<<this<<endl;
delete [] number;
}
int getNextNumber() {
currentPos++;
return number[currentPos];
}
void setNumbers(int position, int value) {
number[position] = value;
}
private:
int* number;
int currentPos;
};
void print1(dummy);
void printboth(dummy, dummy);
int main() {
dummy myNumbers(3);
myNumbers.setNumbers(0,0);
myNumbers.setNumbers(1,1);
dummy myOtherNumbers(3);
myOtherNumbers.setNumbers(0,4);
myOtherNumbers.setNumbers(1,5);
cout<<"Address of myNumbers is "<<&myNumbers<<endl;
cout<<"Address of myOtherNumbers is "<<&myOtherNumbers<<endl;
print1(myNumbers);
printboth(myNumbers, myOtherNumbers);
system("PAUSE");
return 0;
}
void print1(dummy num) {
cout<<"Address of num is "<<&num<<endl;
for (int i=0;i<4;i++)
cout<<"Dummy number1 is "<<num.getNextNumber()<<endl;
return;
}
void printboth(dummy num1, dummy num2) {
cout<<"Address of num1 is "<<&num1<<endl;
cout<<"Address of num2 is "<<&num2<<endl;
for (int i=0;i<4;i++) {
cout<<"Dummy number1 is "<<num1.getNextNumber()<<endl;
cout<<"Dummy number2 is "<<num2.getNextNumber()<<endl;
}
return;
}
答案 0 :(得分:2)
您没有关注rule of three
问题是当你调用print1或printboth时,编译器会调用默认的copy-constructor(因为你没有提供)。该copy-constructor将副本的number成员变量设置为与原始值相同的值。在副本上调用析构函数时,将释放内存。你的原始对象现在指向已经释放的内存,因此当它的析构函数被调用时,你崩溃了(Nik Bougalis)。
void print1(dummy);
void printboth(dummy, dummy);
您可以通过const引用传递虚拟以避免不必要的复制,但强烈推荐您遵循rule of three
void print1(const dummy& );
void printboth(const dummy&, const dummy&);
注意:
您只创建了根本不需要的size =1
数组,只需使用int number;
作为成员。如果number保存动态分配的数组,请尝试使用std::vector<int>
。
getNextNumber存在缺陷,当它被多次调用时,number[currentPos];
访问数字中的边界,这是未定义的行为。
int getNextNumber() {
currentPos++;
return number[currentPos];
}
这意味着建议:
int getNextNumber() const {
return number[currentPos];
}