c++ - 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;
不知道如何解决这个问题并让它按照我想要的方式工作。
解决方案
考虑是否
std::cout << meshFaces[878] << "\n"; //test 3, prove range works
实际上超出范围,访问超过分配内存的末尾meshFaces
但它不是堆中的最后一块内存,因此它返回内存中的某些内容,属于其他分配。
将其打印为指针,没问题。
但它不是指针,它可能是(比如说)文本字符串的一部分。所以试图取消引用坏指针会产生错误。
meshFaces[878]
返回(比方说)(0xff000102030405060708)打印OK。但随后
meshFaces[878][0]
给出了访问冲突。
您的测试#3 不能证明访问范围内;可能是UB。很容易看出,这可能(很容易)不会在运行时崩溃,但第二个下标会。
通过在执行之前检查下标来“修复”numFaces
它。
但是,它会使用一半的内存,并且使用数组数组而不是指针数组会更快更简单。您可以通过使用std::array
which 使数组像普通(结构)类型一样轻松地做到这一点。
using meshdef = std::array<int,3>;
std::vector<meshdef> meshFaces (numFaces);
那么为什么不使用vector
而不用担心手动内存管理呢?您只有一个矢量类开销,而不是每个单元格一个。
推荐阅读
- r - 当我尝试使用 ggplot2 显示多面线图时,为什么会显示 geom_path 警告消息?
- node.js - 是否有任何本机库来检查 Nodejs 中 SSL 证书的有效性
- assembly - 如何生成随机数?(组件 8086)
- javascript - Javascript 对象未使用 Array.Map() 更新
- r - Shiny Plotly 基于颜色的多条平滑线
- java - 如何安全地终止已超时的查询
- rust - 编译器强制我实现 trait 方法,但我的类型永远不会满足方法上的 `Self` 特征绑定
- html - 如何在 Materialise 的 sidenav 中添加子菜单?
- android - 无法将 FirebaseUI 与片段一起使用
- arrays - Symbol.hasInstance 在自定义对象上返回 false