如何使用 C++ 中的指针动态分配和解除分配二维数组?
Posted
技术标签:
【中文标题】如何使用 C++ 中的指针动态分配和解除分配二维数组?【英文标题】:How to dynamically allocate and deallocate a 2D array using pointers in c++? 【发布时间】:2020-10-14 13:32:53 【问题描述】:我想使用指针动态分配然后解除分配二维数组。 我的想法是创建一个指向指针数组的指针,其中每个指针都指向一个 int,这就是我想做的方式。 这些函数是 bool 类型,因为无论操作是否成功,我都想返回一个布尔值。
问题是deallocateTwoDimTable
函数不返回布尔值,所以它似乎根本不起作用。如果我不使用int** table = nullptr;
但未初始化int** table
,那么我会收到错误消息(释放时),我想要释放的内存尚未初始化。
如果我将参数int **table
更改为int **&table
,代码确实有效,但我猜这意味着通过引用而不是使用指针传递。我如何使它工作?非常感谢所有帮助:)
这是我的主要方法:
int main()
int** table = nullptr;
int sizeX = 5; // rows
int sizeY = 3; // columns
bool allocationResult = allocateTwoDimTable(table, sizeX, sizeY);
cout << endl << "allocation result: " << (allocationResult ? "true" : "false") << endl;
bool deallocationResult = deallocateTwoDimTable(table, sizeX);
cout << endl << "deallocation result: " << (deallocationResult ? "true" : "false");
分配函数:
bool allocateTwoDimTable(int **table, int sizeX, int sizeY)
if (sizeX <= 0 || sizeY <= 0) return false;
// allocate 2D table
table = new int*[sizeX];
for(int i = 0; i < sizeX; i++)
table[i] = new int[sizeY];
cout << endl << "Table " << sizeX << " x " << sizeY << endl;
for(int i = 0; i < sizeX; i++)
cout << endl;
for(int j = 0; j < sizeY; j++)
cout << table[i][j] << ", ";
return true;
释放函数:
bool deallocateTwoDimTable(int **table, int sizeX)
if(sizeX <= 0) return false;
for (int k = 0; k < sizeX; k++)
delete[] table[k];
delete[] table;
return true;
【问题讨论】:
如果你在table = new int*[sizeX];
这样的函数中设置table
,你必须通过引用传递,否则你只会设置一个副本,函数结束后会丢失。
为数组之类的东西分配内存的最佳方法是使用std::vector
。在销毁向量时它们更安全,事实上,如果您自己分配内存,您还应该确保在销毁指针之前自己释放内存。你可以使用std::vector
中的函数push_back
。
您的table
数组的元素未初始化。在为这些元素分配值之前,您可能不会尝试从其元素中读取(例如使用cout << table[i][j]
)。
A complete example。此外,请阅读 cmets,了解为什么您的方法(即使您让其发挥作用)存在缺陷。
"但我猜这意味着通过引用而不是使用指针传递" 即使它们是通过引用传递的,它仍然会使用指针。它只是对指针的引用。
【参考方案1】:
当你需要通过引用或指针传递时,如果有机会,最好通过引用传递。
指针可以带空参数,引用不能,使用起来更安全,除非出于某种原因,您特别需要传递空参数,我认为情况并非如此。
请注意,您在打印数组时访问的是未初始化的内存。
还请注意,尽管使用布尔标志来表示分配错误,但您的代码仍然容易受到攻击,更好的方法是使用 std::exception
。
bool allocateTwoDimTable(int** &table, int sizeX, int sizeY)
if (sizeX <= 0 || sizeY <= 0) return false;
// allocate 2D table
table = new int* [sizeX];
for (int i = 0; i < sizeX; i++)
table[i] = new int[sizeY];
cout << endl << "Table " << sizeX << " x " << sizeY << endl;
for (int i = 0; i < sizeX; i++)
cout << endl;
for (int j = 0; j < sizeY; j++)
table[i][j] = i + j; //initializing elements of the array
cout << table[i][j] << ", ";
return true;
bool deallocateTwoDimTable(int (** &table), int sizeX)
if (sizeX <= 0) return false;
for (int k = 0; k < sizeX; k++)
delete[] table[k];
delete[] table;
return true;
int main()
int** table = nullptr;
const int sizeX = 5; // rows
const int sizeY = 3; // columns
try
const bool allocationResult = allocateTwoDimTable(table, sizeX, sizeY);
cout << endl << "allocation result: " << (allocationResult ? "true" : "false") << endl;
const bool deallocationResult = deallocateTwoDimTable(table, sizeX);
cout << endl << "deallocation result: " << (deallocationResult ? "true" : "false");
catch (std::exception& e)
std::cout << e.what();
return EXIT_FAILURE;
return EXIT_SUCCESS;
【讨论】:
【参考方案2】:您必须通过引用传递指针。否则,函数 allocateTwoDimTable 将处理原始指针值的副本。即更改副本不会影响原始指针。
此外,参数sizeX
和sizeY
应该具有size_t
类型,因为通常int
类型可能无法指定所需的数组维度。
函数可以这样声明
bool allocateTwoDimTable( int ** &table, size_t sizeX, size_t sizeY);
注意你创建了未初始化的数组
table[i] = new int[sizeY]
所以输出它们
cout << table[i][j] << ", ";
调用未定义的行为。
【讨论】:
感谢您的详细解答。有没有其他方法可以在没有参考的情况下处理这个问题?我提到它在使用参考时确实有效,但我想知道我是否可以用其他方式做到这一点。 @kabugh 在主要的 cmets 中,我链接到一个答案,该答案显示了它是如何使用指针完成的。 @kabugh 您可以返回指向创建的指针数组的指针,而不是 bool 类型。在这种情况下,您只需检查指针是否等于 nullptr。考虑到您将需要使用不会出现异常的运算符 new。【参考方案3】:看看这个答案https://***.com/a/936709/9936992 他们还提到了使用单个数组来模拟两个 D 数组的可能性
【讨论】:
以上是关于如何使用 C++ 中的指针动态分配和解除分配二维数组?的主要内容,如果未能解决你的问题,请参考以下文章