1

我已将问题缩小到将 2 个对象(包含指针数据成员)传递给一个简单的 void 函数。该函数返回干净,但是当 main() 尝试退出时,它无法回收 2 个对象中的第一个。这是显示问题的示例代码 - 以及用于显示对象在构造、传递和销毁时的地址的打印语句。

如果我只调用“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;
}
4

1 回答 1

2

你没有遵守三法则

问题是当您调用 print1 或 printboth 时,编译器会调用默认的复制构造函数(因为您没有提供)。该复制构造函数将副本的 number 成员变量设置为与原始值相同的值。当在副本上调用析构函数时,内存被释放。您的原始对象现在指向已释放的内存,因此当调用其析构函数时,您会崩溃(Nik Bougalis)。

void print1(dummy);
void printboth(dummy, dummy);

您可以通过 const 引用传递 dummy 以避免不必要的复制,但强烈建议您遵循三规则

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];
   }
于 2013-01-22T01:21:43.683 回答