C++ 在函数中分配内存并返回它 int**转置(int**矩阵、int行、int列) { int**new_mat=new int*[列]; 对于(int i=0;i
我已经编写了这个函数,但感觉有些不对劲,我无法决定是否应该删除新的\u mat函数返回这个值。我应该如何在不使用任何智能指针或其他东西的情况下使用内存进行管理?调用者将使用返回的矩阵 此外,它还可以获得所有权。因此,当矩阵不再需要时,它可以将其删除 另一个选项是为您提供另一个函数,该函数将删除矩阵。然后,调用方必须调用该函数以取消分配动态分配的内存C++ 在函数中分配内存并返回它 int**转置(int**矩阵、int行、int列) { int**new_mat=new int*[列]; 对于(int i=0;i,c++,memory-management,C++,Memory Management,我已经编写了这个函数,但感觉有些不对劲,我无法决定是否应该删除新的\u mat函数返回这个值。我应该如何在不使用任何智能指针或其他东西的情况下使用内存进行管理?调用者将使用返回的矩阵 此外,它还可以获得所有权。因此,当矩阵不再需要时,它可以将其删除 另一个选项是为您提供另一个函数,该函数将删除矩阵。然后,调用方必须调用该函数以取消分配动态分配的内存 但是,智能指针是一个很好的C++特性,我鼓励你给他们一个例子。 此外,由于这个C++,您可以使用 STD::vector < /COD>用于矩阵的
但是,智能指针是一个很好的C++特性,我鼓励你给他们一个例子。
此外,由于这个C++,您可以使用<代码> STD::vector < /COD>用于矩阵的类型。这样,您就不必担心内存管理,因为它的一切都会自动发生。
如果您不想使用任何智能指针和向量,请尝试这样做。 矩阵-是大小为[col][row]的二维动态数组的包装器int** transpose(int** matrix,int row, int column)
{
int** new_mat = new int*[column];
for(int i = 0; i < column; i++)
{
new_mat[i] = new int[row];
}
for(int i = 0; i < row; i++ )
{
for(int j = 0; j < column; j ++)
{
new_mat[j][i] = matrix[i][j];
}
}
return new_mat;
}
#包括
#包括
使用名称空间std;
类矩阵
{
私人:
无符号整数m_行;
无符号整数mu col;
int**m_数据;
公众:
矩阵(无符号整数行,无符号整数列):m_行(行),m_列(列),m_数据(空PTR)
{
alloc();
}
矩阵(const matrix&m):m_行(m.get_行_计数())、m_列(m.get_列_计数())、m_数据(nullptr)
{
alloc();
for(无符号整数i=0;i cout要回答所问的问题,调用者需要释放返回的指针。对于函数中每次使用运算符new
,调用者中都需要相应地使用运算符delete
。当不再需要返回的矩阵时(即删除
d以后不应使用
一个更好的方法——在许多方面,包括不可能忘记释放内存——是避免直接使用指针,避免直接使用运算符new
(或变体)或运算符delete
。相反,使用标准容器,如std::vector(std::vector>
。如果小心使用,标准容器将管理自己的元素,并保留自己大小的记录,因此不存在内存泄漏的可能性(当标准容器不再存在时,它使用的任何动态分配的内存也会被释放)
原则上,您应该能够将函数简化为声明为
void transpose(int **matr_in, int **matr_out, int M, int N)
{
for(int i = 0; i < M; i++)
for(int j = 0; j < N; j++)
matr_out[j][i] = matr_in[i][j];
}
int **create_matrix(int M, int N)
{
int **m = new int*[M];
for(int i = 0; i < M; i++)
m[i] = new int[N];
return m;
}
void delete_matrix(int **m, int M)
{
for(int i = 0; i < M; i++)
delete []m[i];
delete []m;
}
int main()
{
int M = 5, N = 4;
int **m1 = create_matrix(M, N);
// fill matrix m1
int **m2 = create_matrix(N, M);
transpose(m1, m2, M, N);
delete_matrix(m1, M);
delete_matrix(m2, N);
return 0;
}
std::vector转置(const std::vector&matrix);
不需要将行数和列数作为单独的参数传递(向量将保持跟踪)。我将把实现该函数作为一个练习,因为您将学到更多使用该方法的知识。您确实应该考虑矩阵表示:
std::vector<std::vector<int> > transpose(const std::vector<std::vector<int> > &matrix);
现在您有了一个锯齿状数组。虽然std::vector
将使您从所有内存管理工作中解脱出来,但您仍然无法通过以下方式防止锯齿状数组:
int** matrix = ...; // create matrix of 10x12
// doing quite a lot of stuff
delete[] matrix[7]; // possibly even forgotten -> memory leak
matrix[7] = new int[7];
嗯,索引运算符…您实际上想要实现的是,您可以访问矩阵,就像您对数组所做的那样:
template <typename T> // more flexibility: you can use arbitrary data types...
class Matrix // (but you don't _need_ to make a template from)
{
std::vector<std::vector<T>> data;
public:
Matrix(size_t rows, size_t columns)
: data(rows)
{
for(auto& d : data)
d.resize(columns);
}
// the nice thing about using std::vector as data container is
// that default generated move/copy constructors/assignment
// operators and destructor are fine already, so you can forget
// about rule of three or five respectively
// but you need ways to access your data:
size_t rows() { return data.size(); }
size_t columns() { return data.empty() ? 0 : data[0].size(); }
??? operator[](size_t index);
??? operator[](size_t index) const;
};
如果你觉得更舒服,你可以明确三/五的规则:
virtual ~Matrix() = default;
类似于行
类。请注意,如果您坚持在内部使用原始数组,则必须显式编写所有这些数组
然后可以再次通过自由函数进行矩阵转置:
Matrix(Matrix const& other) = default; // rule of three
Matrix& operator=(Matrix const& other) = default; // rule of three
Matrix(Matrix&& other) = default; // rule of five
Matrix& operator=(Matrix&& other) = default; // rule of five
您甚至可以提供一个转置矩阵本身的成员函数,最好:使用上面的转置函数:
Matrix transpose(Matrix const& m)
{
Matrix t(m.columns(), m.rows());
// loops as you had
return t;
}
模板
类矩阵
{
公众:
无效转置()
{
矩阵t(转置(*this));
t、 data.swap(data);//清除t的析构函数中以前拥有的数据。。。
}
您提供了一个函数,返回一个指针数组,该数组包含单独的内存块(每个内存块代表一行)。然后,您还必须同时在同一模块中提供空闲(或删除)函数(以确保内存管理函数完全匹配)
使用vector
并在返回时移动它。无论内存分配到哪里,都适用相同的规则。如果您取消分配并使用它,则行为是未定义的。(正确的解决方案是使用std::vector
,不要担心它。)@George“移动返回”局部变量可能会阻碍优化。不要试图将compi智能化
template <typename T>
class Matrix
{
// all we had so far...
template <typename Data>
class Row
{
Data& data;
friend class Matrix;
Row(std::vector<T>& data)
: data(data)
{ }
public:
// default constructed constructors/operators/destructor
// themselves and being public are fine again...
auto& operator[](size_t index) { return data[index]; }
};
auto operator[](size_t index) { return Row(data[index]); }
auto operator[](size_t index) const { return Row(data[index]); }
};
virtual ~Matrix() = default;
Matrix(Matrix const& other) = default; // rule of three
Matrix& operator=(Matrix const& other) = default; // rule of three
Matrix(Matrix&& other) = default; // rule of five
Matrix& operator=(Matrix&& other) = default; // rule of five
Matrix transpose(Matrix const& m)
{
Matrix t(m.columns(), m.rows());
// loops as you had
return t;
}
template <typename T>
class Matrix
{
public:
void transpose()
{
Matrix t(transpose(*this));
t.data.swap(data); // cleanup of previously owned data done in t's destructor...
}
int** transpose(int** matrix, int row, int column)
{
int** new_mat = new int*[column];
...
return new_mat;
}
//when free the mat, cols is not concerned;
void free_mat(int** matrix, int rows)
{
int i;
for(i= 0; i< rows; i++)
delete[] matrix[i];
delete[] matrix;
}
//use the function as:
int** m2 = transpose(m1, rows, cols);
...
free_mat(m2, cols);
//after free_mat(), m2 still holds the address.
//so make it nullptr.
m2 = NULL;
int* mat = new int[rows * cols];
//transfer mat[iRow][iCol] to mat[iRow * cols + iCol];
return mat;