首页 > 解决方案 > C++ 动态数组访问冲突,读写位置

问题描述

尝试在包含 int 值的数组内的数组内创建一个数组,我已经知道所有 3 个的长度。

更改或读取值时,我遇到访问冲突,想象它是在循环内创建数组,但我需要在循环外访问和更改这些值,因为循环的目的是在初始数组中创建更多数组。

    //numFaces are defined by clipboard text being converted with std::stoi
    int ** meshFaces = new int*[numFaces];
    for(int i = 0; i < numFaces; i++) meshFaces[i] = new int[3];

    //expected meshFaces[num][2] = 0;


    std::cout << meshFaces[878] << "\n"; //test 3, prove range works

    //both cases cause access violation
    meshFaces[878][1] = 0; //test #2
    std::cout << meshFaces[878][1] << "\n"; //test


    // finished ref
    // 0 = Vertices
    // 1 = Normals
    // 2 = UVs
    // 
    // meshFaces[num][0][2] = 0

    //remove array from memory
    for(int i = 0; i < numFaces; i++) delete[] meshFaces[i];
    delete[] meshFaces;

不知道如何解决这个问题并让它按照我想要的方式工作。

标签: c++arrays

解决方案


考虑是否
std::cout << meshFaces[878] << "\n"; //test 3, prove range works
实际上超出范围,访问超过分配内存的末尾meshFaces但它不是堆中的最后一块内存,因此它返回内存中的某些内容,属于其他分配。

将其打印为指针,没问题。

但它不是指针,它可能是(比如说)文本字符串的一部分。所以试图取消引用坏指针会产生错误。

meshFaces[878]返回(比方说)(0xff000102030405060708)打印OK。但随后 meshFaces[878][0]给出了访问冲突。

您的测试#3 不能证明访问范围内;可能是UB。很容易看出,这可能(很容易)不会在运行时崩溃,但第二个下标会。

通过在执行之前检查下标来“修复”numFaces它。

但是,它会使用一半的内存,并且使用数组数组而不是指针数组会更快更简单。您可以通过使用std::arraywhich 使数组像普通(结构)类型一样轻松地做到这一点。

using meshdef = std::array<int,3>;
std::vector<meshdef> meshFaces (numFaces);

那么为什么不使用vector而不用担心手动内存管理呢?您只有一个矢量类开销,而不是每个单元格一个。


推荐阅读