在二维数组上使用 delete[] 时访问冲突 [重复]

Posted

技术标签:

【中文标题】在二维数组上使用 delete[] 时访问冲突 [重复]【英文标题】:Access violation when using delete[] on a 2-dim array [duplicate] 【发布时间】:2020-10-04 16:24:27 【问题描述】:

我正在使用 C++ 进行矩阵乘积练习(实际上是斯特拉森算法)。由于给定的最大数据集达到 2048 * 2048,我尝试使用 delete[] 释放临时内存。但是它说其中存在内存访问冲突,为什么?

以下是一些可能有帮助的代码:

struct Matrix 
    int row, column;
    int** m;

    Matrix(int row, int column) 
        m = new int* [2048];
        for (int i = 0; i < row; i++)
            m[i] = new int[2048];
    

    ~Matrix() 
        if (m != NULL) 
            for (int i = 0; i < 2048; i++) 
                delete[] m[i]; //access violation happens here
            
            delete[] m;
        
    
;

Matrix matAdd(Matrix matA, Matrix matB) 
    Matrix matR = Matrix(matA.row, matA.column);
    for (int i = 0; i < matA.row; i++)
        for (int j = 0; j < matA.column; j++) 
            matR.m[i][j] = matA.m[i][j] + matB.m[i][j];
        
    return matR;


//There are some other functions below but the structure is basically the same

【问题讨论】:

您必须至少为您的类实现一个复制构造函数和一个赋值运算符。有关更多信息,请参阅重复的问题。您确实了解您正在按值传递 并返回 矩阵,这会创建重复的对象。如果没有显式的复制构造函数,多个副本具有相同的指针,然后它们的析构函数将尝试多次删除相同的指针。希拉里随之而来。或者,或者,忘记 newdeleteing 任何东西,并使用 std::vector,它会为你做所有事情。这就是它的用途。 在重复链接中,请特别注意管理资源部分。该部分准确描述了问题所在。 【参考方案1】:

数组中从索引行开始的指针没有被初始化。

Matrix(int row, int column) 
    m = new int* [2048];
    for (int i = 0; i < row; i++)
        m[i] = new int[2048];

    // Initialize rest elements with null pointer.
    for (int i = row; i < 2048; i++)
        m[i] = nullptr;

其余的初始化将修复崩溃,但随后您将在双重释放时崩溃。原因:您使用类的副本,因此您需要实现复制构造函数和赋值运算符或使用共享指针而不是原始指针。默认副本使指针指向相同的分配对象。

另请参阅答案https://***.com/a/1403180/6752050 以及如何使用单个分配创建二维矩阵的示例。

【讨论】:

【参考方案2】:

您应该考虑使用std::vector&lt;std::vector&lt;int&gt;&gt;

您的课程缺少复制构造函数和复制赋值,我确定这是双重释放的情况。

【讨论】:

以上是关于在二维数组上使用 delete[] 时访问冲突 [重复]的主要内容,如果未能解决你的问题,请参考以下文章

二维内核中的银行冲突

删除动态分配的二维数组时发生错误?

使用 c# 访问二维数组时出错

新/删除导致访问冲突

java多线程访问同一个数组,存在并发问题吗,每个线程访问的是数组的不同部分,不存在冲突

遍历数组和线程时访问冲突