超载运算符中的分段错误=

Tim*_*Tim 2 c++ overloading segmentation-fault

我在为一个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;    
}
Run Code Online (Sandbox Code Playgroud)

有人有一些线索吗?感谢致敬!

小智 14

*this = rhs;
Run Code Online (Sandbox Code Playgroud)

调用operator =(),这是你正在编写的函数.提示无限递归,堆栈溢出,崩溃.

此外,如果您使用std :: vector而不是C样式数组,则可能根本不需要实现operator =().

  • 如果您更喜欢C数组而不是向量,那么您就错了,并为自己做了大量不必要的工作. (5认同)
  • 您无法正确编写赋值运算符的事实意味着您可能不知道与使用动态分配的数组相关的许多其他陷阱.这意味着你绝对应该使用std :: vector <>.喜欢C阵列不是一个原因,而是缺乏对真实情况的理解. (2认同)

小智 8

如上所述,你有无限的递归; 但是,除此之外,这是实现op =的一种万无一失的方法:

struct T {
  T(T const& other);
  T& operator=(T copy) {
    swap(*this, copy);
    return *this;
  }
  friend void swap(T& a, T& b);
};
Run Code Online (Sandbox Code Playgroud)

写一个正确的拷贝ctor和swap,并为你处理异常安全和所有边缘情况!

拷贝参数按值传递,然后改变.当销毁副本时,处理当前实例必须销毁的任何资源.这遵循当前的建议并干净地处理自我分配.


#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;
}
Run Code Online (Sandbox Code Playgroud)

注意到它与手动管理构件(p)或RAII/SBRM式部件(小号).