我的课程出现问题,当我尝试将其中一个对象添加到矢量时,似乎只出现了问题。
Assignement工作正常除非在尝试插入向量时发生(这会在释放内存时导致以下错误:抛出异常:读取访问冲突this->elements
为{{1} })。
这是我的assignement运算符和我的复制构造函数。请注意,0xCEDECEDF
是elements
指针。
int**
以下是 Matrice& Matrice::operator=(const Matrice& other)
{
if (elements)
{
for (size_t i = 0; i < numberoflines; ++i)
if (elements[i])
delete[] elements[i];
delete[] elements;
}
id = other.id;
numberofcols= other.numberofcols;
numberoflines= other.numberoflines;
elements = new int*[numberoflines];
for (size_t i = 0; i < numberoflines; ++i)
elements[i] = new int[numberofcols];
for (size_t i = 0; i < numberoflines; ++i)
for (size_t j = 0; j < numberofcols; ++j)
elements[i][j] = other.elements[i][j];
return *this;
}
Matrice::Matrice(const Matrice& other) {
*this = other;
}
(矩阵)类的标题:
Matrice
以下是构造函数和析构函数:
#pragma once
#include<iostream>
class Matrice {
public:
friend std::istream& operator>>(std::istream&, Matrice&);
friend std::ostream& operator<<(std::ostream&, const Matrice&);
Matrice(const unsigned, const unsigned, const unsigned);
Matrice();
Matrice(const Matrice&);
~Matrice();
Matrice& operator=(const Matrice&);
int operator~()const;
bool operator<(const Matrice&)const;
private:
unsigned id;
unsigned numberoflines;
unsigned numberofcols;
int** elements;
};
最后我只是在主要:
中执行此操作 Matrice::Matrice(unsigned id, unsigned numberoflines, unsigned numberofcols) {
this->id = id;
this->numberoflines = numberoflines;
this->numberofcols = numberofcols;
elements = new int*[numberoflines];
for (size_t i = 0; i < numberoflines; ++i)
elements[i] = new int[numberofcols];
}
Matrice::Matrice() {
numberofcols = 1;
numberoflines = 1;
elements = new int*[numberoflines];
for (size_t i = 0; i < numberoflines; ++i)
elements[i] = new int[numberofcols];
}
Matrice::~Matrice() {
if (elements) {
for (size_t i = 0; i < numberoflines; ++i)
if (elements[i])
delete[] elements[i];
delete[] elements;
}
}
答案 0 :(得分:1)
您的复制构造函数调用赋值运算符。赋值运算符以以下代码开头:
Run -> Edit configuration
这会在复制构造函数中造成麻烦,因为复制构造函数中的任何内容都没有初始化if (elements)
{
for (size_t i = 0; i < numberoflines; ++i)
if (elements[i])
delete[] elements[i];
delete[] elements;
}
,因此它将指向内存中的随机位置。在您的情况下,那是elements
。因此0xCEDECEDF
非零,在C ++中总是评估为elements
,因此我上面引用的代码将尝试删除实际上未分配的内存。
将行true
添加到您的复制构造函数后,elements = nullptr;
的值现在被解释为elements
,因此会跳过false
块,并取消分配代码未被调用。
执行此操作的另一种方法in C++11,恕我直言更明智,是在类声明中初始化if
:
nullptr
这样,每次创建新对象时,编译器都会初始化 unsigned numberofcols;
int** elements = nullptr; // CHANGE HERE
};
,并且您不必担心忘记在其中一个构造函数中执行此操作。
顺便说一句,你的副本构造函数有疏忽;您应首先确保elements
和this
不是同一个对象。