我得到了一个段错误,因为我认为我的临时变量在运营商使用之前被销毁(释放已分配的内存)。这是我主要的代码:
int main(int argc, char *argv[])
{
Bcd b1 = Bcd(100), b2 = Bcd(20), b3 = Bcd(50);
b3 += b1 + b2;
return 0;
}
我在析构函数中放了一个print语句,输出如下:
sum
destroying 120
sum
segmentation fault
我不明白为什么会这样。看来临时变量b1 + b2在被第二次使用之前被破坏了。临时变量b1 + b2是否应该有效直到主线的那一行结束?我是否错误地实现了运算符重载函数,或者我的代码是否存在其他问题,我没有考虑?
我的自定义类定义如下:
class Bcd
{
public:
Bcd();
Bcd(const char* num);
Bcd(const Bcd &num);
Bcd(const int num);
~Bcd();
int getLength() const;
Bcd& operator=(const Bcd &rhs);
Bcd& operator+=(const Bcd &rhs);
const Bcd& operator +(const Bcd &rhs) const;
std::string toString() const;
private:
//takes a character and places is at number[index]. If that index does
//not exist, allocates memory for that number and then sets number[index].
void modifyNumber(char num, int index);
char* number;
int length;
int size;
};
.c文件的重要部分在这里:
Bcd& Bcd::operator +=(const Bcd &rhs){
int minSize, i;
char result[2] = {0};
printf("sum\n");
if(this->getLength() < rhs.getLength())
minSize = this->getLength();
else
minSize = rhs.getLength();
for(i = 0; i < minSize; i++) //SEGFAULT from accessing rhs.number[0]
this->modifyNumber(this->number[i] + rhs.number[i], i);
if(this->getLength() < rhs.getLength()){
for(;i < rhs.getLength(); i++)
this->modifyNumber(rhs.number[i], i);
}
else{
for(;i < this->getLength(); i++)
this->modifyNumber(this->number[i], i);
}
return *this;
}
const Bcd& Bcd::operator +(const Bcd &rhs) const
{
return Bcd(*this) += rhs;
}
Bcd::Bcd(const Bcd &num)
{
length = num.length;
size = num.size;
//allocate memory for number
number = new char[length];
for(int i = 0; i < length; i++)
number[i] = num.number[i];
}
答案 0 :(得分:3)
确切地说它应该如何发生。可能更正确的说,它不是临时的b1 + b2
被破坏,而是在你的二进制Bcd(*this) += rhs
实现中的临时+
被破坏。
您对+
const Bcd& Bcd::operator +(const Bcd &rhs) const
{
return Bcd(*this) += rhs;
}
尝试返回绑定到临时的引用。在函数退出之前临时被破坏,引用仍然挂起。来电者会收到一个“死亡”的信息。参考。行为未定义。
您无法从二进制+
返回引用。你根本没有任何东西可以返回引用。相反,按值返回
Bcd Bcd::operator +(const Bcd &rhs) const
{
return Bcd(*this) += rhs;
}
这个实现确实会返回一个临时的b1 + b2
。那个临时性不会过早被破坏。
答案 1 :(得分:3)
一个问题是operator +应该返回对象的副本,而不是引用。我认为你的代码创建了一个临时的并返回它的引用,这是一个很大的NO。
您的编译器应该警告过您。如果每次使用GCC使用-W -Wall。它会有很大的帮助。
现在这很奇怪。我用我的GCC对此进行了测试,如果我使用-O2或-O3优化进行编译,我只会收到警告。