You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

三维顶点数组邻接指针向量初始化后为空问题求助

嘿,我来帮你捋捋这个问题——你说创建了三维Vertex对象数组,每个对象的邻居指针向量(DiagNeighbours、DirectNeighbours)初始化后再访问就空了,这种情况我在做网格细分的时候碰到过好多次,大概率是这几个常见坑:

可能的原因与对应解决方案

1. 初始化时压根没往向量里加元素

最容易犯的错就是,你可能只是声明了这两个vector,但忘记把相邻Vertex的指针push进去。比如你可能写了:

// 错误示例:只初始化了空vector,没添加邻居
vertices[i][j][k].DirectNeighbours = vector<Vertex*>();

正确的做法是先确定每个Vertex的相邻索引,再把对应指针塞进去。比如针对三维网格的正方向邻居:

// 假设三维数组是vertices[x][y][z],maxX/maxY/maxZ是各维度的长度
if (x < maxX - 1) {
    vertices[x][y][z].DirectNeighbours.push_back(&vertices[x+1][y][z]);
}
if (y < maxY - 1) {
    vertices[x][y][z].DirectNeighbours.push_back(&vertices[x][y+1][z]);
}
if (z < maxZ - 1) {
    vertices[x][y][z].DirectNeighbours.push_back(&vertices[x][y][z+1]);
}
// 负方向和对角线邻居同理

2. 数组拷贝导致指针失效

如果你的三维数组是通过拷贝构造或者赋值操作复制的,那原来的邻居指针会指向旧数组的内存地址,而新数组的元素在新的内存位置,这时候指针就变成了野指针,访问时要么显示为空,要么直接崩溃。比如:

// 错误示例:直接拷贝数组,导致指针指向无效内存
vector<vector<vector<Vertex>>> newGrid = oldGrid;

解决办法是不要直接拷贝整个数组,如果需要复制网格,要重新遍历新数组,逐个重新设置所有邻居指针;或者改用shared_ptr<Vertex>来管理对象,但对于这种规则网格,只要处理好内存生命周期,原始指针其实更高效。

3. 数组的内存生命周期太短

如果你的Vertex数组是在某个局部函数里创建的,然后你把指针带出了这个函数,那当函数执行完毕,局部数组被销毁,邻居指针就变成了悬空指针,访问时可能表现为空(或者出现未定义行为)。比如:

// 错误示例:局部数组的指针被返回,后续访问会出问题
Vertex*** createSubdividedCube() {
    Vertex*** grid = new Vertex**[8];
    // 初始化数组和邻居...
    return grid;
}

解决办法是确保数组的生命周期覆盖所有使用邻居指针的代码——比如把数组放在全局作用域,或者用vector<vector<vector<Vertex>>>这样的容器来管理,让它在需要的时候一直存在。

4. 初始化顺序搞反了

如果你在创建Vertex对象的同时就设置邻居指针,但对应的邻居对象还没被创建出来,那指针会指向未初始化的内存,后续访问时自然是空的。正确的顺序应该是:

  1. 先创建所有Vertex对象,填充好它们的position属性;
  2. 再遍历所有Vertex,逐个设置DiagNeighbours和DirectNeighbours的指针。

快速排查小技巧

你可以在初始化完邻居指针后,立刻在同一个作用域里打印某个Vertex的邻居数量:

cout << "Vertex [0][0][0] has " << vertices[0][0][0].DirectNeighbours.size() << " direct neighbours" << endl;

如果这里能输出正确的数量,但后面访问时为空,那大概率是数组拷贝或生命周期的问题;如果这里就输出0,那肯定是初始化时没正确添加邻居元素。

内容的提问来源于stack exchange,提问作者Ryoku

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 04:02:48