我在为一个FeatureRandomCounts类重载赋值运算符时遇到了一个seg错误,该类具有_rects作为其指针成员指向FeatureCount和大小rhs._dim的数组,并且其他日期成员是非指针:
FeatureRandomCounts & FeatureRandomCounts::operator=(const FeatureRandomCounts &rhs)
{
if (_rects) delete [] _rects;
*this = rhs; // segment fault
_rects = new FeatureCount [rhs._dim];
for (int i = 0; i < rhs._dim; i++)
{
_rects[i]=rhs._rects[i];
}
return *this;
}
有人有一些线索吗?谢谢和问候!
答案 0 :(得分:14)
*this = rhs;
调用operator =(),这是你正在编写的函数。提示无限递归,堆栈溢出,崩溃。
另外,如果你使用std :: vector而不是C风格的数组,你可能根本不需要实现operator =()。
答案 1 :(得分:7)
如上所述,你有无限的递归;但是,除此之外,这是实现op =:
的一种万无一失的方法struct T {
T(T const& other);
T& operator=(T copy) {
swap(*this, copy);
return *this;
}
friend void swap(T& a, T& b);
};
编写正确的副本ctor和swap,并为您处理异常安全和所有边缘情况!
copy 参数通过值传递然后更改。当 copy 被销毁时,将处理当前实例必须销毁的所有资源。这遵循current recommendations并干净地处理self-assignment。
#include <algorithm>
#include <iostream>
struct ConcreteExample {
int* p;
std::string s;
ConcreteExample(int n, char const* s) : p(new int(n)), s(s) {}
ConcreteExample(ConcreteExample const& other)
: p(new int(*other.p)), s(other.s) {}
~ConcreteExample() { delete p; }
ConcreteExample& operator=(ConcreteExample copy) {
swap(*this, copy);
return *this;
}
friend void swap(ConcreteExample& a, ConcreteExample& b) {
using std::swap;
//using boost::swap; // if available
swap(a.p, b.p); // uses ADL (when p has a different type), the whole reason
swap(a.s, b.s); // this 'method' is not really a member (so it can be used
// the same way)
}
};
int main() {
ConcreteExample a (3, "a"), b (5, "b");
std::cout << a.s << *a.p << ' ' << b.s << *b.p << '\n';
a = b;
std::cout << a.s << *a.p << ' ' << b.s << *b.p << '\n';
return 0;
}
请注意,它适用于手动管理的成员( p )或RAII / SBRM样式的成员( s )。
答案 2 :(得分:4)
*this = rhs; // segment fault
这绝对是不的方式。您以递归方式调用=
,而不是调用内置赋值运算符。逐个分配变量。不要偷懒。
答案 3 :(得分:3)
以下一行:
*this = rhs; // segment fault
将以递归方式调用operator=()
函数,导致堆栈溢出。
您应该将其替换为各个成员字段的直接分配。
As Neil said,使用类似std::vector<>
之类的内容可以消除代码中的大部分责任。如果由于某种原因您不能或不想使用std::vector<>
,您可能还需要考虑为您的赋值运算符使用'swap idiom'。这将使函数异常安全(如果FeatureCount
数组的内存分配失败并抛出异常,则分配给的原始对象将保持不变)。如下所示:
void FeatureRandomCounts::swap( FeatureRandomCounts& other)
{
FeatureCount* tmp_rects = other._rects;
int tmp_dim = other._dim; // or whatever type _dim is
// similarly for other members of FeatureRandomCounts...
// now copy the other contents to
this->_rects = other._rects;
this->_dim = other._dim;
// assign other members of rhs to lhs
other._rects = tmp_rects;
other._dim = tmp_dim;
// etc.
return;
}
现在,您的作业可能如下所示:
FeatureRandomCounts & FeatureRandomCounts::operator=(const FeatureRandomCounts &rhs)
{
FeatureRandomCounts tmp( rhs); // make a copy
tmp.swap( *this); // swap the contents of the copy and *this
return *this;
// the contents of tmp (which has the old
// stuff that was in *this) gets destructed
}
请注意,您需要一个合适的复制构造函数才能使用此工具,但鉴于Big 3 rule,您需要一个合适的复制文件。