运行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
相关产品推荐
相关产品推荐

