如何使用 C++ 中的指针动态分配和解除分配二维数组?

     2023-02-21     107

关键词:

【中文标题】如何使用 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 &lt;&lt; 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 将处理原始指针值的副本。即更改副本不会影响原始指针。

此外,参数sizeXsizeY 应该具有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++ 中正确使用动态分配的多维数组 [重复]

】如何在C++中正确使用动态分配的多维数组[重复]【英文标题】:Howtoproperlyworkwithdynamically-allocatedmulti-dimensionalarraysinC++[duplicate]【发布时间】:2016-03-0818:21:09【问题描述】:如何在C++中定义动态多维数组?比如二维数组?我尝试... 查看详情

C 和 C++:释放已分配指针的一部分

...42【问题描述】:假设我分配了一个指针来保存4096字节。如何释放C中的最后1024个字节?在C++中呢?相反,如果我想释放first1024个字节,并保留其余部分(两种语言)怎么办?从中间解除分配怎么样(在我看来,这需要将它分成... 查看详情

指针&&动态内存分配

C++中的动态内存分配机制c++中使用new和delete来完成在堆上对动态内存的分配和释放。注.所有指针都应该被初始化 如果指针指向的动态内存被释放或没有指向合法的地址,就应该将指针设置为nullptr,否则内存泄漏。变量:  d... 查看详情

C++:使用迭代器构造一个二维动态分配的数组

】C++:使用迭代器构造一个二维动态分配的数组【英文标题】:C++:usingiteratortoconstructa2Ddynamicallyallocatedarray【发布时间】:2020-06-0316:18:59【问题描述】:我是C++新手,我正在尝试创建一个具有动态分配二维数组的构造函数的类。... 查看详情

在 C++ 中使用动态内存分配创建二维数组

】在C++中使用动态内存分配创建二维数组【英文标题】:Creatinga2DArrayusingdynamicmemoryallocationinC++【发布时间】:2021-12-2013:01:19【问题描述】:我正在尝试使用动态内存分配来实现二维数组。这是我的代码:#include<iostream>usingnam... 查看详情

二维数组C++的动态分配

】二维数组C++的动态分配【英文标题】:DynamicAllocationoftwo-dimensionalarrayC++【发布时间】:2015-02-1001:42:30【问题描述】:您好,我是C++新手,我需要动态分配二维数组。没有错误,但在运行时,当我设置订单和第一行时,我得到一... 查看详情

在 C++ 中的 2D 动态内存分配数组中释放分配的内存

...近发布了一个关于此的问题,但这是一个不同的问题。我使用动态内存分配创建了一个二维数组,使用矩阵后,我们需要通过删除它来释放内存,我不明白为什么我们不能只使用delete[]matrix来删除它而不 查看详情

c++建立动态二维数组(代码片段)

C++建立动态二维数组主要有两种方法:1.使用数组指针,分配一个指针数组,将其首地址保存在b中,然后再为指针数组的每个元素分配一个数组                       int**b=newint*[row];      ... 查看详情

C++:使用函数为二维数组分配内存时出错

】C++:使用函数为二维数组分配内存时出错【英文标题】:C++:Errorwhileallocatingmemoryforatwodimensionalarrayusingfunctions【发布时间】:2016-08-0117:36:37【问题描述】:我试图理解按引用传递和按值传递。在这个程序中,我有一个二维数组... 查看详情

C++:静态指针、静态对象和动态内存分配

】C++:静态指针、静态对象和动态内存分配【英文标题】:C++:Staticpointers,staticobjectsanddynamicmemoryallocation【发布时间】:2016-02-0305:13:12【问题描述】:考虑下面的代码段:#include<iostream>usingnamespacestd;classppublic:int*q;p()q=newint(100)... 查看详情

如何定义一个动态的数组?

参考技术A利用这一特性定义一个指针数组。int**p=newint*[size];//定义指针数组 int*p[5];// 假若知道二维数组的行数为5然后对指针数组中的每一个指针分配一个一维数组空间,这样便动态定义了二维数组事实上,我认为指针数... 查看详情

如何在构造函数中访问类变量以在不使用 C++ 中的 this 指针的情况下分配它们

】如何在构造函数中访问类变量以在不使用C++中的this指针的情况下分配它们【英文标题】:howtoaccessclassvariableinsideaconstructortoassignthemwithoutusingthispointerinC++【发布时间】:2019-10-1915:57:56【问题描述】:当类变量和参数名称相同时... 查看详情

如何在 C++ 中为二维对象数组分配内存? [复制]

】如何在C++中为二维对象数组分配内存?[复制]【英文标题】:Howtoallocatememorytoa2Darrayofobjectsinc++?[duplicate]【发布时间】:2021-11-3012:52:57【问题描述】:存在三个类Zoo、ZooObject和Animal。如下所述声明ZooObjects的2D数组是否有效?如果... 查看详情

需要有关 C++ 中二维数组的动态内存分配的帮助

...然无法理解它的每一个细节。有人可以解释一下以下代码如何动态地为数组分配内存。真的 查看详情

C++ 动态内存分配与结构中的数组

】C++动态内存分配与结构中的数组【英文标题】:C++dynamicmemoryallocationwitharraysinastructure【发布时间】:2013-07-1017:31:19【问题描述】:有类似的问题,但它们都是用C语言,而不是C++,所以我问了一个新问题。我一直关注C++tutorial,... 查看详情

c++中new和delete的用法

在C++编程中,使用new分配的数组可用delete释放。这里释放的是动态分配的数组空间,而不是静态分配的数组空间,详细步骤:1、例如,我们动态创建了一个一维int数组arr,现在需要将它释放。2、这时只需要使用delete[]数组名即... 查看详情

无法分配给 C++ 中的指针数组

】无法分配给C++中的指针数组【英文标题】:cannotassigntoarrayofpointersinc++【发布时间】:2021-07-2603:23:56【问题描述】:我需要在c++中保留一个指针数组。我有一个集合来保存我班级的对象。然后我需要遍历集合并将每个项目的指... 查看详情

如何在 C++ 中动态分配数组

】如何在C++中动态分配数组【英文标题】:HowtodynamicallyallocatearraysinC++【发布时间】:2016-02-2104:44:49【问题描述】:我知道如何在C中为数组动态分配空间。可以这样做:L=(int*)malloc(mid*sizeof(int));内存可以通过以下方式释放:free(L)... 查看详情