C语言实现矩阵行重排后后续打印值异常是什么原因?
问题根因
出现该异常的核心原因是**remove_line执行后,system数组的最后两个指针指向了同一块内存地址**,修改其中一个的内容会同步影响另一个,具体流程拆解如下:
- 当
qty=3时,system初始有3个指针,分别指向3块独立的行内存:ptr0(存第一行)、ptr1(存第二行)、ptr2(存第三行) - 执行
remove_line(system, 0, 3)时,函数内部逻辑为:- 先
free(system[0]),释放ptr0指向的内存 - 把指针向前平移:
system[0] = system[1](即指向ptr1)、system[1] = system[2](即指向ptr2) - 平移结束后,
system[2]没有被修改,仍然指向ptr2,此时system[1]和system[2]都指向同一块内存ptr2
- 先
- 重排矩阵的打印循环中,你是边赋值边打印:
i=0:打印system[0](ptr1的内容4.0 0.0 2.0),无修改i=1:打印system[1](ptr2的原始内容2.0 3.0 0.0),此时还没触发i=qty-1的赋值逻辑,输出正确i=2:先把aux的值写入system[2](也就是ptr2),再打印写入后的值0.0 3.0 2.0,此时ptr2的内容已经被修改,而system[1]也指向ptr2,所以system[1]的内容同步变成了0.0 3.0 2.0
- 第三次打印时,直接读取所有行的内容,
system[1]已经被同步修改,所以出现了两行重复的异常结果。
修复方案
你要实现的是「把第一行移动到最后」的功能,完全不需要释放内存再拷贝内容,直接交换行指针即可,逻辑更简单也不会出错:
void changes_equation_order(double** system, unsigned int qty) { // 直接交换指针完成行移动,不需要额外的拷贝和free操作 double* temp = system[0]; for (int i = 0; i < qty -1; i++) { system[i] = system[i+1]; } system[qty-1] = temp; // 后续打印逻辑保持不变即可 for(int i = 0; i < qty; i++) { for(int j = 0; j < qty; j++) { printf("%.1lf ", system[i][j]); } printf("\n"); } }
如果要保留你原来的remove_line逻辑,需要在平移指针后给最后一行重新分配内存,避免两个指针指向同一块地址。
内容的提问来源于stack exchange,提问作者Another
相关产品推荐
相关产品推荐

