为何这段C语言程序会抛出Segmentation fault异常?
你的代码出现Segmentation Fault的原因及修复方案
咱们直接来拆解问题——你虽然给二维数组的两层都分配了内存,但代码里有几个致命的逻辑错误,直接导致了段错误:
1. 内层循环的变量更新错误(最直接的段错误诱因)
看这段代码:
for (int j = 1; j < (**(drevo + i)) + 1; i++)
你初始化的循环变量是j,循环条件也依赖j,但循环的增量语句却写成了i++!这会让i在每次内层循环时疯狂递增,很快就会超出你一开始分配的n个元素的范围(外层循环的i本来只应该从0到n-1)。当i >= n时,访问drevo[i]就是在越界访问未分配的内存,直接触发Segmentation Fault。
正确的写法应该把增量改成j++:
for (int j = 1; j < (**(drevo + i)) + 1; j++)
2. 输入输出的指针使用逻辑错误
printf("%d jlk", *(drevo));这里*(drevo)是drevo[0]的地址(也就是第一个一维数组的首地址),不是你要打印的整数值。如果想打印当前drevo[i]的第一个元素,应该写成**(drevo + i)或者更直观的drevo[i][0]。scanf("%d", *(drevo + 2));你固定写了drevo + 2,也就是往drevo[2]的首地址输入值,但如果n小于3的话,drevo[2]根本没分配内存,这也会触发段错误。从逻辑上看,你应该是想往当前drevo[i]的第j个位置输入,所以应该写成*(drevo + i) + j或者&drevo[i][j]。
3. 内存分配未做合法性检查(好习惯必备)
虽然这不是这次段错误的直接原因,但每次malloc后检查是否分配成功是避免空指针操作的关键:
int **drevo = (int **) malloc(n * sizeof(int *)); if (drevo == NULL) { perror("malloc failed for drevo"); return 1; } // 内层malloc同理 drevo[i] = (int *) malloc(10000 * sizeof(int)); if (drevo[i] == NULL) { perror("malloc failed for drevo[i]"); // 还要清理已分配的内存避免泄漏 for (int k = 0; k < i; k++) { free(drevo[k]); } free(drevo); return 1; }
修正后的完整代码示例
#include <stdio.h> #include <stdlib.h> int main() { int n; scanf("%d", &n); int **drevo = (int **) malloc(n * sizeof(int *)); if (drevo == NULL) { perror("Failed to allocate memory for drevo"); return 1; } for (int i = 0; i < n; i++) { drevo[i] = (int *) malloc(10000 * sizeof(int)); if (drevo[i] == NULL) { perror("Failed to allocate memory for drevo[i]"); // 清理已分配内存 for (int k = 0; k < i; k++) { free(drevo[k]); } free(drevo); return 1; } // 读取当前数组的第一个元素,作为后续输入的数量 scanf("%d", &drevo[i][0]); for (int j = 1; j < drevo[i][0] + 1; j++) { printf("%d jlk\n", drevo[i][0]); scanf("%d", &drevo[i][j]); } } // 使用完毕后释放所有内存 for (int i = 0; i < n; i++) { free(drevo[i]); } free(drevo); return 0; }
另外,代码里还有几个未使用的变量(k、stukaza、parameter),可以直接删掉避免编译警告。
内容的提问来源于stack exchange,提问作者Nejc Ahtik
相关产品推荐
相关产品推荐

