#include"algorithm.h"
int** transpose(int**po, int &m, int &n)
{
int*p = (int*)malloc(m*n*sizeof(int));//转置矩阵空间
int**pn = (int**)malloc(n*sizeof(int*));//转置矩阵数组指针
//指针备份
int *save = po[0];
int *nSave = p;
//布置转置矩阵
// [1 2 3 4 5 6] --> [1 4 2 5 3 6]
for (int j = 0; j < n; j++)
{
for (int i = 0; i < m; i++)
{
/*注意这里都有自增,指针的值变化了,就可能出现堆头错误!*/
*p++ = *po[i];//按地址录入元素
po[i] = po[i] + 1;//更新地址
}
}
//还原指针指向堆头,坑!!!
p = nSave;
po[0] = save;
//布置转置矩阵数组指针
for (int j = 0; j < n; j++)
{
pn[j] = &p[j*m];
}
//释放原矩阵空间
free(po[0]);
free(po);
swap(m, n);
return pn;
}
int main()
{
int m, n;
scanf("%d%d", &m, &n);
int**p = new_arr2(m, n);
if (!p)
return -1;
scan_arr2(p, m, n);
p = transpose(p, m, n);
print_arr2(p, m, n);
free(p[0]);
free(p);
return 0;
}
指针变化后不再指向原处,如果指针指向的是堆(malloc来的),则free时不注意就会导致堆头错误,上面有二级指针的话二级指针也无法正确解包拿到自增前的数据,比如这次实验就产生矩阵转置后全是杂乱值的情况,那是一级指针已经飘了,二级也遭殃了,所以要注意指针的变化是有潜在的陷阱的。
该程序改进方法是不要对传进的参数直接修改,而是新建临时指针变量用于处理,就像ps一般不直接对原图处理而是新建副本再处理。