C语言中向二维数组添加行并赋值后特定单元格值异常的问题求助
问题根源:内存越界访问
我一眼就看到问题出在add_one_row_2Dvector函数里的内存分配逻辑——你给新行分配空间时,错误地用当前行数作为列数,而不是矩阵实际需要的固定列数cols。
具体分析
你的矩阵是固定3列的,但每次添加行时:
- 第一次添加行(rows从1变2),你给新行分配了
2 * sizeof(double)的空间(因为(*rows)此时是2),但我们需要的是3列。这时候访问attrac[1][2]已经属于内存越界,只是当时内存里刚好是正确的值,没立刻暴露问题。 - 第二次添加行(rows从2变3),realloc后给新行分配3个double的空间,但之前的第二行(索引1)只有2个元素的空间,此时再访问
attrac[1][2]就会踩到不属于它的内存区域,被其他操作覆盖成0.0——这就是典型的未定义行为。
另外还有两个小bug:
- 你在
realloc之后才检查tmp是否为NULL,如果realloc失败,tmp是空指针,后续的tmp[i] = malloc(...)会直接崩溃。 - 那个多余的for循环完全没必要,因为只需要给新添加的那一行分配空间,循环只执行一次。
修复后的代码
先修正add_one_row_2Dvector函数,新增cols参数来指定列数,同时调整内存分配的顺序(先检查realloc结果):
void add_one_row_2Dvector(double ***attrac, int *rows, int cols) { // 先增加行数,再尝试重新分配 (*rows)++; double **tmp = realloc(*attrac, (*rows) * sizeof(double *)); if (tmp == NULL) { // realloc失败,恢复行数并报错 (*rows)--; printf("Couldn't realloc 2D vector...\n"); return; } // 给新行分配对应列数的空间 tmp[*rows - 1] = malloc(cols * sizeof(double)); if (tmp[*rows - 1] == NULL) { // 新行分配失败,回滚操作 (*rows)--; free(tmp); printf("Couldn't allocate new row...\n"); return; } (*attrac) = tmp; }
然后修改调用这个函数的地方,传入cols参数:
void do_everything(double ***attrac, int *rows, int cols, double *count, double *X, int indexX, int indexY) { add_one_row_2Dvector(attrac, rows, cols); // 新增cols参数 assign_values_to_new_row(attrac, (*rows), X, indexX, indexY, &count); print_matrix((*attrac), (*rows), cols); }
修复后效果
运行修正后的代码,你会看到attrac[1][2]的值会一直保持2.0,不会再被意外覆盖:
Matrix (rows = 1): 1.2 0.1 1.0 count = 1.0 i = 0 Matrix (rows = 2): 1.2 0.1 1.0 2.2 1.1 2.0 count = 2.0 i = 1 Matrix (rows = 3): 1.2 0.1 1.0 2.2 1.1 2.0 3.2 2.1 3.0 count = 3.0 ...
额外注意事项
- 内存分配后一定要检查返回值,避免空指针解引用导致崩溃。
- 规则二维数组的列数要固定,不能随行数动态变化,否则很容易出现越界问题。
- 内存越界是C语言里的“隐形杀手”,表现可能随机(这次是变0,下次可能直接崩溃),一定要严格控制数组的访问范围。
内容的提问来源于stack exchange,提问作者Luguecos
相关产品推荐
相关产品推荐

