我收到错误“munmap_chunk():指针无效”,我不知道为什么。使用MultipliedByMatrix
方法时出现问题。它无法正确删除在此方法中创建的矩阵。
#include "matrix.h"
Matrix::Matrix(int matr_size) {
size = matr_size;
Matr = new int *[size];
for(int i = 0; i < size; i++)
Matr[i] = new int[size];
for(int i = 0 ; i < size; i++)
for(int j = 0; j < size; j++)
Matr[i][j] = rand() % 100;
std::cout << "New matrix is created" << std::endl;
}
Matrix::~Matrix() {
for(int i = 0; i < size; i++)
delete[] Matr[i];
delete[] Matr;
Matr = NULL;
std::cout << "Matrix is deleted" << std::endl;
}
Matrix Matrix::MultipliedByMatrix(Matrix OtherMatr) {
Matrix new_matr = Matrix(this->GetSize());
int new_value;
for(int i = 0 ; i < size; i++)
for(int j = 0; j < size; j++) {
new_value = 0;
new_value += Matr[j][i] * OtherMatr.GetValue(i, j);
new_matr.SetValue(i, j, new_value);
}
return new_matr;
}
int Matrix::GetSize() {
return size;
}
int Matrix::GetValue(int i, int j) {
return Matr[i][j];
}
void Matrix::SetValue(int i, int j, int value) {
Matr[i][j] = value;
}
答案 0 :(得分:1)
你自己写过Matrix
课吗?如果是这样,我打赌问题是你没有副本或移动构造函数。如果是这样,编译器将为您生成一个。这将复制size和Matr 的值,但它不会创建指向数组的副本。当你写:
return new_matr;
这会创建一个新矩阵(使用复制构造函数 - 只复制指针),然后调用new_matr
的析构函数(删除指向的内存)。然后调用函数处理垃圾内存,当它试图最终删除结果时,所有地狱都会破坏
您还需要编写一个移动赋值运算符。
或者将Matr设为std::vector<int>
(长度&#39;大小&#39;平方),然后写:
int Matrix::GetValue(int i, int j) {
return Matr[i*size+j];
}
(和其他功能类似)。 std::vector
有一个正确的副本和移动构造函数,以及正确的赋值行为 - 所以它一切正常。 (它也会快得多 - 你保存一个完整的指针间接。)
答案 1 :(得分:0)
这不是问题的分析性答案,而是解决(或更好地规避)问题的建议。
如果可以,请尽量避免自己处理内存。 (你很可能真的可以避免它。)
您可以在#34; 1D or 2D array, what's faster?&#34;问题上阅读我的答案。为了获得冗长的表达式,为什么使用你正在使用的那种内存布局可能是不可取的。
此外,您将找到一个(但尚未经过测试)如何在std::vector
之上实现简单矩阵容器的示例。
您可以查看该方案,并尝试根据需要实施自己的方案。与您的实现相比,该设计具有以下几个优点:
int
以及许多其他类型一起使用。std::vector
正在处理资源并执行&#34;脏工作&#34;为你。如果您仍想使用RAW-Pointer方法(出于学术目的或其他目的):
阅读What is meant by Resource Acquisition is Initialization (RAII)?并尝试了解答案。
正确阅读What is The Rule of Three?并确保您已实施(最好遵守RAII概念)这些功能:
std::bad_alloc
的情况下保持异常安全。示例:您的构造函数更好一点&#39;方式:
Matrix::Matrix(std::size_t const matr_size) // you have a size here, no sign required
{
Matr = new int*[matr_size];
std::size_t allocs(0U);
try
{ // try block doing further allocations
for (std::size_t i = 0; i < matr_size; ++i)
{
Matr[i] = new int[matr_size]; // allocate
++allocs; // advance counter if no exception occured
for(std::size_t j = 0; j < matr_size; j++)
{
Matr[i][j] = rand() % 100;
}
}
}
catch (std::bad_alloc & be)
{ // if an exception occurs we need to free out memory
for (size_t i = 0; i < allocs; ++i) delete[] Matr[i]; // free all alloced rows
delete[] Matr; // free Matr
throw; // rethrow bad_alloc
}
}