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

运行C语言代码出现Segmentation Fault错误,求修复方案

解决你的Segmentation Fault问题

嘿,我帮你定位到了程序触发段错误的核心原因——不是scanf的锅,而是你声明的指针数组根本没分配内存,导致scanf往非法内存地址写数据了。咱们一步步理清楚:

1. 野指针是段错误的元凶

你代码里声明了四个指针数组:

int* R[holes];
int* X[holes];
int* Y[holes];
int* Z[holes];

这些数组里的每个元素都是int*类型,但它们都是野指针——没有指向任何有效的内存空间。当你在循环里执行scanf("%d %d %d %d", R[i], X[i], Y[i], Z[i]);时,scanf会尝试把读取到的整数写入这些野指针指向的地址,这直接触发了内存访问违规,也就是你遇到的Segmentation Fault。

怎么修复?

其实你根本不需要用指针数组,直接用普通的一维数组就能搞定:

// 改成普通数组,每个元素都是int类型
int R[holes];
int X[holes];
int Y[holes];
int Z[holes];

然后scanf的时候要传入变量的地址(用&取地址符):

scanf("%d %d %d %d", &R[i], &X[i], &Y[i], &Z[i]);

如果holes的值特别大,栈空间不够用,那可以改用动态内存分配(堆内存):

// 给每个数组分配堆内存
int* R = malloc(holes * sizeof(int));
int* X = malloc(holes * sizeof(int));
int* Y = malloc(holes * sizeof(int));
int* Z = malloc(holes * sizeof(int));

// 一定要检查内存分配是否成功,避免空指针
if (R == NULL || X == NULL || Y == NULL || Z == NULL) {
    fprintf(stderr, "内存分配失败啦!\n");
    return 1;
}

// 循环里的scanf同样要传地址
scanf("%d %d %d %d", &R[i], &X[i], &Y[i], &Z[i]);

// 程序结束前别忘了释放内存,避免内存泄漏
free(R); free(X); free(Y); free(Z);

2. 还有几个潜在的小问题要注意

  • 变长数组的栈溢出风险:你用了double sizeOfPlate[p];这种变长数组,如果p特别大(比如几万),栈空间很容易不够用。建议改成动态内存分配:
    double* sizeOfPlate = malloc(p * sizeof(double));
    if (sizeOfPlate == NULL) {
        fprintf(stderr, "内存分配失败!\n");
        return 1;
    }
    
  • 输出格式不一致:当p == 1时,你输出的是printf("100.0000000");,不仅少了换行符,而且只有7位小数,和其他分支的9位不一致,建议改成printf("100.000000000\n");
  • 别忘了检查scanf的返回值:如果输入格式不对,scanf会读取失败,后续程序就会乱套。比如可以加个检查:
    if (scanf("%d %d", &holes, &p) != 2) {
        fprintf(stderr, "输入的前两个数格式不对哦!\n");
        return 1;
    }
    

修复后的完整代码

#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <stdio.h>

int main(){
    int holes;
    int p;
    // 检查前两个输入是否读取成功
    if (scanf("%d %d", &holes, &p) != 2) {
        fprintf(stderr, "读取holes和p失败!\n");
        return 1;
    }
    double plates = (double) p;
    // 用普通数组存储洞的参数
    int R[holes];
    int X[holes];
    int Y[holes];
    int Z[holes];
    // 动态分配内存存储每个盘子的大小
    double* sizeOfPlate = malloc(p * sizeof(double));
    if (sizeOfPlate == NULL) {
        fprintf(stderr, "内存分配失败!\n");
        return 1;
    }

    for(int i = 0; i < holes; i++){
        // 检查每个洞的参数是否读取成功
        if (scanf("%d %d %d %d", &R[i], &X[i], &Y[i], &Z[i]) != 4) {
            fprintf(stderr, "读取第%d个洞的参数失败!\n", i+1);
            free(sizeOfPlate);
            return 1;
        }
    }

    if(holes == 0){
        double eachSize = 100.0 / plates;
        for(int i = 0; i < p; i++){
            sizeOfPlate[i] = eachSize;
        }
        for (int i = 0; i < p; ++i) {
            printf("%.9lf\n", sizeOfPlate[i]);
        }
    } else if(p == 1){
        printf("100.000000000\n");
    } else{
        printf("Wrong result\n");
    }

    // 释放动态分配的内存
    free(sizeOfPlate);
    return 0;
}

最后提个小建议

以后写C语言程序的时候,但凡用到指针,一定要确认它指向的是有效的内存空间;还有输入输出相关的函数,记得检查返回值,能避免很多奇奇怪怪的问题哦!

内容的提问来源于stack exchange,提问作者Gentle

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 07:27:48