2011-03-04 69 views
5

我有一个类Foo对我已经重载+操作如下副本:返回与运算符重载

Foo Foo::operator+(const Bar &b) 
{ 
    Foo copy = (*this); 
    if (someCondition) return copy; 
    //snip 
} 

对我来说,这看起来是合理的。但是,每当我返回副本时,Visual Studio都会向我发出“可能由于堆损坏”导致的错误。我所做的是否有问题?

编辑:与更多信息更新。

错误消息:

Windows已经在 SAMPLE.EXE触发一个断点。

这可能是由于 堆的腐败,这表明在 SAMPLE.EXE或任何它 加载的DLL的一个错误。

这也可能是由于用户 按F12而sample.exe有 的重点。

输出窗口可能有更多 诊断信息。

复制构造:

Foo::Foo(const Foo&p) 
{ 
    some_pointer = p.get_some_pointer(); 
    some_value = p.get_some_value(); 
} 

代码它打破到:

//within dbgheap.c 
    extern "C" _CRTIMP int __cdecl _CrtIsValidHeapPointer(
      const void * pUserData 
      ) 
    { 
      if (!pUserData) 
       return FALSE; 

      if (!_CrtIsValidPointer(pHdr(pUserData), sizeof(_CrtMemBlockHeader), FALSE)) 
       return FALSE; 

      return HeapValidate(_crtheap, 0, pHdr(pUserData)); 
    } 
+4

你能告诉我们'Foo'的拷贝构造函数吗? – 2011-03-04 07:37:31

+1

什么是错误代码? – metdos 2011-03-04 07:42:29

+0

@ Space_C0wb0y @metdos我已更新了更多信息 – socks 2011-03-04 07:50:49

回答

3

这类型的错误通常与的多个缺失(或释放)相关联的相同的指针或一些更隐晦的情况(从一堆获取并释放到不同的堆中,但这可能不是这种情况)。

我会做的第一件事是看一个析构函数,并检查你是不是浅拷贝和双删除。例如,使用以下代码:

// buggy!!! 
struct test { 
    int * data; 
    test() : data(new int[5]) {} 
    ~test() { delete [] data; } 
    test(test const & rhs) : data(rhs.data) {} 
    test& operator=(test const & rhs) { 
     data = rhs.data; 
    } 
}; 
int main() { 
    test t1;   // 5 ints allocated int t1.data 
    test t2(t1); // no memory allocated, t2.data == t1.data 
} // t2 out of scope: t2.~test() => delete t2.data 
    // t1 out of scope: t1.~test() => delete t1.data but both are the same: double delete 

如果是这种情况,您可以决定是否要浅拷贝或进行深拷贝。在第二种情况下,复制构造函数(和赋值运算符)应该分配它们自己的内存,而在第二种情况下,您必须确保内存不会被释放两次。

与指针一样,最好将资源管理委托给外部(预先构建的)类。如果是独特的所有权(和深层副本),则应该使用std::auto_ptr(或者在C++ 0x中为std::unique_ptr或者增强变体)。在第二种情况下,使用boost::shared_ptr(或在C++ 0x中为std::shared_ptr)将确保数据共享并且只能删除一次。

+1

如果类不拥有指针所指向的对象,那么首选参考。 – 2011-03-04 09:06:55

+1

@Space:一个首选项,将有效地呈现类不可分配(这可能是一个算术运算符的类奇怪)... – visitor 2011-03-04 11:33:08

+0

@visitor:对,没有考虑到这一点。 – 2011-03-04 11:36:53