我是否违反了C++编码惯例,编写了一个在main()
之外分配2D数组的辅助函数?因为我的应用程序需要许多N维数组,所以我希望确保遵循相同的过程。演示我正在做什么的原型:
#include <iostream>
// my helper function which allocates the memory for a 2D int array, then returns its pointer.
// the final version will be templated so I can return arrays of any primitive type.
int** make2DArray(int dim1, int dim2)
{
int** out = new int* [dim1];
for (int i = 0; i < dim2; i++) { out[i] = new int[dim2];}
return out;
}
//helper function to deallocate the 2D array.
void destroy2DArray(int** name, int dim1, int dim2)
{
for (int i = 0; i < dim2; i++) { delete[] name[i]; }
delete[] name;
return;
}
int main()
{
int** test = make2DArray(2,2); //makes a 2x2 array and stores its pointer in test.
//set the values to show setting works
test[0][0] = 5;
test[0][1] = 2;
test[1][0] = 1;
test[1][1] = -5;
// print the array values to show accessing works
printf("array test is test[0][0] = %d, test[0][1] = %d, test[1][0] = %d, test[1][1] = %d",
test[0][0],test[0][1],test[1][0],test[1][1]);
//deallocate the memory held by test
destroy2DArray(test,2,2);
return 0;
}
我担心的是这可能不是内存安全的,因为我似乎在使用它的函数之外分配内存(潜在的范围外错误(。当我制作一个小数组时,我可以对数组进行读写操作,但当我扩展它时,我会担心代码可能会访问和更改这些值。
我可能可以通过创建一个数组类来回避这些问题,该类将这些函数作为成员,但我很好奇这是C++风格和作用域的边缘情况。
分配这样的2D数组和根据语句声明int ary[10][10]
这样的局部变量时得到的结果是有区别的
我担心这个操作可能不安全,因为它似乎正在为外部的数组分配内存使用它的功能(潜在的范围外错误(
我猜你还没有完全理解。
您正在堆上分配数组。声明像int ary[10][10]
这样的局部变量会将其放置在堆栈上。在后一种情况下,您需要担心在基于作用域的生存期之外没有引用该内存;也就是说,以下是完全错误的:
//DON'T DO THIS.
template<size_t M, size_t N>
int* make2DArray( ) {
int ary[M][N];
return reinterpret_cast<int*>(ary);
}
int main()
{
auto foo = make2DArray<10, 10>();
}
因为ary
是函数的本地,并且当调用make2DArray<10,10>
创建的堆栈帧消失时,函数返回的指针将悬空。
堆分配是另一回事。它的寿命超过了创建它的范围。它一直持续到被删除。
但无论如何,正如其他人在评论中所说,您的代码看起来像C而不是C++。更喜欢std::vector<std::vector<int>>
,而不是自己滚动。
如果必须使用数组并且对std::vector
过敏,请将2d数组(矩阵(创建为内存中的一个连续区域:
int * matrix = new int [dim1 * dim2];
如果要将值设置为零:
std::fill(matrix, (matrix + (dim1 * dim2)), 0);
如果要访问<row, column>
:上的值
int value = matrix[(row * column) + column];
由于矩阵是一个分配,您只需要一个delete
:
delete [] matrix;