循环给二维struct赋值触发Access violation writing location报错如何解决
错误原因
- 二维数组第二维长度申请不足:你为每个
points[i]申请的长度是SCALE - 1,但你通过floor(rand() * SCALE)生成的fy取值范围是[0, SCALE-1],当fy等于SCALE-1时,访问points[fx][fy]就会触发越界写。 - struct成员未初始化:你通过new申请的intpos结构体成员属于内置类型,不会自动初始化,
numb的初始值是随机垃圾值,累加后很容易超出合理范围。 - prtcls数组越界:一方面
numb初始值异常会导致索引直接越界,另一方面你先执行numb +=1再用累加后的值当索引,即使numb初始为0,当第10个粒子存入时索引会变成10,超出prtcls数组[0,9]的合法索引范围,同时索引0的位置会被浪费。
修复方案
- 修正二维数组申请长度:将第二维的申请长度从
SCALE-1改为SCALE,匹配fy的取值范围。 - 初始化intpos成员:申请每行内存后,遍历初始化每个元素的
numb为0。 - 修正prtcls赋值逻辑,增加边界校验:调整索引使用顺序,先使用当前numb赋值再累加,同时增加索引边界判断避免超出数组长度。
修复后核心代码示例:
typedef struct { int prtcls[10],numb; } intpos; int main(int argc, char** argv) { particle_t* particles; intpos** points = new intpos*[(int)SCALE]; for (int i = 0; i < (int)SCALE; i++) { // 修复1:第二维长度改为SCALE intpos* row = new intpos[(int)SCALE]; points[i] = row; // 修复2:初始化所有元素的numb为0 for(int j=0; j<(int)SCALE; j++){ points[i][j].numb = 0; } } cudaMallocHost(&particles, sizeof(particle_t)*NUM_PARTICLES); // 随机初始化位置/方向 for (int i = 0; i < NUM_PARTICLES; i++) { particles[i].x =( (float)rand() / (float)RAND_MAX) * SCALE ; particles[i].y = ((float)rand() / (float)RAND_MAX) * SCALE; particles[i].phi = ((float)rand() / (float)RAND_MAX) * 2 * 3.14; particles[i].flrx = floor(particles[i].x) ; particles[i].flry = floor(particles[i].y) ; int fx = particles[i].flrx; int fy = particles[i].flry; // 修复3:增加边界判断,避免prtcls越界 if(points[fx][fy].numb < 10){ int curn = points[fx][fy].numb; points[fx][fy].prtcls[curn] = i; points[fx][fy].numb += 1; } // 可选:如果单格粒子数可能超过10,建议将prtcls改为std::vector<int>动态扩容 } // 后续业务逻辑... // 记得释放申请的内存避免泄漏 }
内容的提问来源于stack exchange,提问作者Mohammad Jafari
相关产品推荐
相关产品推荐

