复制构造函数和重载赋值运算符的堆损坏错误
Heap Corruption error with Copy constructor and overloaded assignment operator
我是一名学生,所以我为没有使用正确的论坛协议而预先道歉。我在这个问题上搜索了几个小时,我的同学都帮不上忙。我的任务是创建一个复制构造函数、重载赋值运算符 (=( 和一个析构函数("三大"(,C++来管理堆上的数组。 我在VS13中下面写的内容会产生正确的输出,但是我收到调试错误: 检测到堆损坏:C++ CRT 检测到应用程序在堆缓冲区结束后写入内存谁能给我一些指导,我什至不知道去哪里看。谢谢!!
//copy constructor
myList::myList(const myList& source){
cout << "Invoking copy constructor." << endl;
array_capacity = source.array_capacity; //shallow copy
elements = source.elements; //shallow copy
delete[] arrayPointer;
arrayPointer = new double(source.array_capacity); //deep copy
for (int i = 0; i < array_capacity; i++) //copy array contents
{
arrayPointer[i] = source.arrayPointer[i];
}
}
//overloaded assignment operator
myList& myList::operator=(const myList& source){
cout << "Invoking overloaded assignment." << endl;
if (this != &source){
array_capacity = source.array_capacity; //shallow copy
elements = source.elements; //shallow copy
delete[] arrayPointer; //delete original array from heap
arrayPointer = new double(array_capacity); //deep copy
for (int i = 0; i < source.array_capacity; i++) {//copy array contents
arrayPointer[i] = source.arrayPointer[i];
}
}
return *this;
}
//destructor
myList::~myList(){
cout << "Destructor invoked."<< endl;
delete[] arrayPointer; // When done, free memory pointed to by myPointer.
arrayPointer = NULL; // Clear myPointer to prevent using invalid memory reference.
}
你的代码有几个问题。首先,您在arrayPointer
上调用delete
,但它尚未初始化为任何内容。实际上,这最终可能会删除您已经分配的内存,或者导致delete
实现中的超出或资产。其次,当您初始化它时,您正在分配一个初始化为 source.array_capacity
值的单个double
。请注意下面行中使用的括号。
arrayPointer = new double(source.array_capacity);
这肯定会在复制过程中导致未定义的行为,因为您最终会访问数组边界之外的元素。上面的行存在于复制构造函数和复制赋值运算符中,应该使用方括号,如下所示:
arrayPointer = new double[source.array_capacity];
您也从不检查是否有任何元素存储在 myList
的source
实例中。在这种情况下,您可能应该将nullptr
(或 C++03 中的NULL
(分配给arrayPointer
。
作为旁注,您实际上不需要将NULL
分配给析构函数中的arrayPointer
。一旦对象被销毁,它就消失了,任何事后访问它的尝试都会导致未定义的行为。
Obvlious 船长已经指出了复制构造函数中的问题。
您会注意到,复制构造函数和赋值运算符包含许多相同的代码,但存在细微差别。事实上,这可能是你最终出错的方式(赋值运算符需要delete[]
旧值,但复制构造函数不需要。
代码重复是不好的,因为它会导致像这样的微妙错误蔓延。您可以在此处使用的一个很好的模式是所谓的复制和交换习惯用法。
要点是你定义了复制构造函数,你也定义了swap
.然后您可以免费获得作业。 这是有效的swap
因为它比赋值运算符更容易正确实现,另一个主要好处是不会出错(您不必担心内存不足错误等(。
在你的代码中;保留你的固定复制构造函数,你可以在类定义中添加:
friend void swap( myList &a, myList &b )
{
std::swap( a.array_capacity, b.array_capacity );
std::swap( a.arrayPointer, b.arrayPointer );
std::swap( a.elements, b.elements );
}
现在赋值运算符非常简单:
myList& myList::operator=(const myList &source)
{
myList temp(source);
swap(*this, temp);
return *this;
}
当前对象的旧资源由 temp
的析构函数删除。此版本甚至不需要检查自我分配std::swap(x, x)
因为它是明确定义的。
这甚至可以通过按值而不是按引用source
来进一步优化,如链接页面上所述。
- 在C++中检测到堆损坏错误
- AMQP-CPP:TCP 处理程序中的管道损坏错误
- 与强制转换相关的堆损坏错误
- 如何修复C ++中的"堆已损坏"错误?
- 双重释放或损坏错误(找不到错误?
- 对于我的类函数,我得到双重释放或损坏错误
- 为什么我的作业操作员给出了损坏错误
- 为什么 delete[] 会导致堆损坏错误
- 为什么我的visual c++在堆栈损坏的情况下没有触发堆栈损坏错误
- c++运行程序时出现堆已损坏错误
- 范围末尾的C 双免费或损坏错误
- Vector访问中出现内存损坏错误
- C 双免费或损坏错误
- 包含链接列表的链接列表给出了堆的损坏错误:原因
- 在Windows上立即检测到堆损坏错误.如何
- 双重释放或损坏错误
- 使用删除 [] 和新(放置)运算符的可视C++堆损坏错误
- 调试 MS VC++ 2005 中的堆损坏错误
- 堆损坏错误;无法发布 cv::Mat opencv
- 使用auto_ptr时出现内存损坏错误