抛出异常:读取访问冲突。 **dynamicArray** 为 0x1118235。发生了

Posted

技术标签:

【中文标题】抛出异常:读取访问冲突。 **dynamicArray** 为 0x1118235。发生了【英文标题】:Exception thrown: read access violation. **dynamicArray** was 0x1118235. occurred 【发布时间】:2019-04-04 14:42:53 【问题描述】:
#include "pch.h"
#include <iostream>
#include <string>
using namespace std;
int **dynamicArray ;
int ROWS, COLUMNS;

//---------------------------------
int input_matrix(int ROWS, int COLUMNS)


    //---------------------------------------
    //memory allocated for elements of rows.
    int **dynamicArray = new int *[ROWS];

    //memory allocated for  elements of each column.
    for (int i = 0; i < ROWS; i++)
        dynamicArray[i] = new int [COLUMNS];

    //free the allocated memory
    for (int i = 0; i < ROWS; i++)
        delete[] dynamicArray[i];
    delete[] dynamicArray;
    //-------------------------------------

    for (int i = 0; i < ROWS; i++)
    
        for (int j = 0; j < COLUMNS; j++)
        
            cin >> dynamicArray[i][j];
        
    
    return 0;

//---------------------------------------------
int print_matrix(int **Array)

    for (int k = 0; k < ROWS; k++)
    
        for (int m = 0; m < COLUMNS; m++)
        
            cout << Array[k][m];
            if (m == COLUMNS)
            
                cout << "\n";
            
        
    

    return 0;



//---------------------------------
int main()

    cin >> ROWS;
    cin >> COLUMNS;
    input_matrix(ROWS, COLUMNS);
    print_matrix(dynamicArray);


这段代码定义了一个矩阵并获取输入并将它们放入矩阵的成员中,但是每次我运行这段代码时,都会出现读取访问冲突错误:

cin >> dynamicArray[i][j];

以下是完整的详细信息: 抛出异常:读取访问冲突。 dynamicArray 为 0x1118235。发生了

我该怎么办?

提前谢谢你。

【问题讨论】:

您分配然后立即释放input_matrix中的数组。一旦你释放了阵列,你就不应该触摸/使用它。但是在该函数结束时,您使用已释放的数组。 你应该释放dynamicArraymain的内存,完成后。 您还有很多其他小问题:为什么不使用vector?不要使用全局变量。 using namespace std 被认为是坏的。在print_matrix m 永远不会等于COLUMNS 我能想出为什么这个错误对你来说不明显的唯一原因是你没有意识到“释放内存”的作用——你甚至在你的代码中有一条注释说“免费分配的内存”。是的,您填充了矩阵,但这并不意味着“现在我不再需要内存,因为矩阵已填充并且现在保存我的值”。如果我错了,那就这样吧,但同样,这是您认为在实际使用矩阵之前释放内存会起作用的唯一合理原因。 【参考方案1】:

如果你在 Valgrind 下运行程序,它会准确地告诉你出了什么问题:

==6939== Invalid read of size 8
==6939==    at 0x1092C9: input_matrix(int, int) (53083248.cpp:30)
==6939==    by 0x1093FA: main (53083248.cpp:59)
==6939==  Address 0x4d7ecc0 is 0 bytes inside a block of size 16 free'd
==6939==    at 0x48373EB: operator delete[](void*) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==6939==    by 0x109296: input_matrix(int, int) (53083248.cpp:23)
==6939==    by 0x1093FA: main (53083248.cpp:59)
==6939==  Block was alloc'd at
==6939==    at 0x483654F: operator new[](unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==6939==    by 0x1091D3: input_matrix(int, int) (53083248.cpp:14)
==6939==    by 0x1093FA: main (53083248.cpp:59)
==6939== 
==6939== Invalid write of size 4
==6939==    at 0x496FFF0: std::istream::operator>>(int&) (istream.tcc:194)
==6939==    by 0x1092EA: input_matrix(int, int) (53083248.cpp:30)
==6939==    by 0x1093FA: main (53083248.cpp:59)
==6939==  Address 0x4d7ed10 is 0 bytes inside a block of size 8 free'd
==6939==    at 0x48373EB: operator delete[](void*) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==6939==    by 0x10927D: input_matrix(int, int) (53083248.cpp:22)
==6939==    by 0x1093FA: main (53083248.cpp:59)
==6939==  Block was alloc'd at
==6939==    at 0x483654F: operator new[](unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==6939==    by 0x10922A: input_matrix(int, int) (53083248.cpp:18)
==6939==    by 0x1093FA: main (53083248.cpp:59)
==6939== 
==6939== Invalid read of size 8
==6939==    at 0x10934D: print_matrix(int**) (53083248.cpp:42)
==6939==    by 0x10940C: main (53083248.cpp:60)
==6939==  Address 0x0 is not stack'd, malloc'd or (recently) free'd
==6939== 
==6939== 
==6939== Process terminating with default action of signal 11 (SIGSEGV)
==6939==  Access not within mapped region at address 0x0
==6939==    at 0x10934D: print_matrix(int**) (53083248.cpp:42)
==6939==    by 0x10940C: main (53083248.cpp:60)

对内存的读取和写入均已释放,而对 dynamicArray 的取消引用从未分配过。

要解决这些问题,您需要确保您的内存生命周期适合您使用它们时,并避免在input_matrix() 中隐藏dynamicArray

我建议您避免使用原始的 new[]delete[] - 更喜欢使用为您拥有资源的容器和智能指针,并自动从它们的析构函数中释放它。

【讨论】:

【参考方案2】:

您的程序存在多个问题。让我一一列举。

    正如其中一个 cmets 所述,您立即 分配内存后立即释放内存。绝对这个 将导致分段错误或内存访问冲突时 您访问已释放的内存。 当你分配内存时,你不是 将分配的内存指针分配给全局指针 dynamicArray 相反,您正在使用 函数 input_matrix 中的同名。作为这个指针 变量范围在您丢失内存的函数内结束 分配。因此,您将再次面临分段错误或内存 print_matrix 函数内部的访问冲突。 在内部 for 循环中的 print_matrix 函数内部,您正在检查 m==COLUMNS 是否打印新行,这永远不会发生,因为 m 总是小于 COLUMNS。 最后,正如前面的答案所暗示的,当您使用 C++ 时,使用带有智能指针的向量比使用数组和原始指针更好地管理内存。

遵循 sn-p 可以解决这些问题。

#include <iostream>
#include <string>
using namespace std;
int **dynamicArray ;
int ROWS, COLUMNS;

//---------------------------------
int input_matrix(int ROWS, int COLUMNS)

    //---------------------------------------
    //memory allocated for elements of rows.
    dynamicArray = new int *[ROWS];

    //memory allocated for  elements of each column.
    for (int i = 0; i < ROWS; i++)
        dynamicArray[i] = new int [COLUMNS];

//    cout<<"Input array values\n";

    for (int i = 0; i < ROWS; i++)
    
        for (int j = 0; j < COLUMNS; j++)
        
            cin>>dynamicArray[i][j];
        
    
    return 0;


void free_matrix_memory()

    cout<<"freeing allocated memory\n";
    //free the allocated memory
    for (int i = 0; i < ROWS; i++)
        delete[] dynamicArray[i];
    delete[] dynamicArray;
    //-------------------------------------


//---------------------------------------------
int print_matrix(int **Array)

    cout<<"printing matrix\n";
    for (int k = 0; k < ROWS; k++)
    
        for (int m = 0; m < COLUMNS; m++)
            cout << Array[k][m];
        cout << "\n";
    
    return 0;


//---------------------------------
int main()

    cout<<"Row and column values\n";
    cin>> ROWS;
    cin>> COLUMNS;
    input_matrix(ROWS, COLUMNS);
    print_matrix(dynamicArray);
    free_matrix_memory();

仍然可以为您进行许多改进,例如避免使用全局变量等,我将由您来完成这些改进。

【讨论】:

非常感谢,你太棒了。【参考方案3】:

在这种情况下,没有理由手动滚动您的内存管理。改用std::vector(这是一个动态数组),甚至使用实际的矩阵库,例如“Eigen”。

【讨论】:

这应该是评论而不是答案。 我认为这是一个完美的答案。 OP 甚至在问“我该怎么办?” 仍然是一个建议,因为我们不知道是否允许他使用std::vector 或第三方库。 是的,因为问题被标记为 c++。 我确信这是一个很好的建议,但它对于错误的解释有点短。 (实际上,这个问题比很多问题要好 - 如果您删除本地包含,它实际上会编译。诚然,它只是阻止等待输入,但您不能拥有一切!)。这看起来更像是一个很好的评论而不是对我的回答。

以上是关于抛出异常:读取访问冲突。 **dynamicArray** 为 0x1118235。发生了的主要内容,如果未能解决你的问题,请参考以下文章

C++ Int 似乎没有初始化并抛出异常:读取访问冲突

抛出未处理的异常:读取访问冲突。 x 是 0x20B4112

抛出异常:读取访问冲突。这是0xBF13D000

C++ Battle4Zion 项目抛出未处理的异常:读取访问冲突。 **this** 是 nullptr。发生了

为什么调试器会抛出“读取访问冲突。这是nullptr”例外吗?

DLL代理调用LoadLibrary导致异常:访问冲突读取位置0x00000250