使用双指针与scanf填充二维整数数组时出现无限循环问题
问题原因与解决方案
为什么会无限循环?
你用双指针动态分配的二维数组本质是指针数组——每一行的内存通过单独的malloc调用分配,各行内存块在物理上不连续。
你的assign函数假设&mat[0][0]到&mat[N-1][M-1]是连续内存区域,用p从首元素遍历到尾元素。但实际上,当p走到第一行最后一个元素的下一个位置时,它指向的是第一行内存块外的未知地址,这个地址远小于最后一行最后一个元素的地址(因各行内存不连续),所以循环条件p <= &mat[N-1][M-1]永远成立,导致无限循环。
另外,scanf("%d", &*p)可简化为scanf("%d", p),因为p本身就是int*类型,&*p等价于p。
解决方案
方案1:按行按列遍历(推荐)
放弃内存连续的假设,用嵌套循环逐行逐列填充,这是动态二维数组的标准遍历方式:
void assign(int** mat, int N, int M) { for (int i = 0; i < N; i++) { for (int j = 0; j < M; j++) { printf("Give an integer number : "); scanf("%d", &mat[i][j]); } } }
方案2:分配连续内存实现单指针遍历
如果一定要用单指针连续遍历,需将二维数组的所有元素分配在同一块连续内存中,再让行指针指向对应位置:
修改主函数的内存分配部分:
int main() { const int N=4; const int M=4; // 分配存储行指针的数组 int **p = (int**)malloc(sizeof(int*) * N); // 分配连续的N*M个int的内存块 int *data = (int*)malloc(sizeof(int) * N * M); if (p == NULL || data == NULL) { printf("No allocated memory\n"); return EXIT_FAILURE; } // 让每个行指针指向连续内存的对应行起始位置 for (unsigned i = 0; i < N; ++i) { p[i] = data + i * M; } assign(p, N, M); Display(p, N, M); // 释放内存:先释放连续数据块,再释放行指针数组 free(data); free(p); return 0; }
此时原assign函数可正常工作,还能简化scanf参数:
void assign(int** mat, int N, int M) { int *p; for (p = &mat[0][0] ; p <= &mat[N-1][M-1] ; p++) { printf("Give an integer number : "); scanf("%d", p); // 简化后的写法 } }
内容的提问来源于stack exchange,提问作者hogar
相关产品推荐
相关产品推荐

