You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何这段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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 09:46:08