调用scanf()时出现Segmentation Fault的C语言问题排查
C语言程序段错误与zsh trace trap问题解决
我的C语言程序在定义磁盘大小时出现Segmentation Fault(段错误),后续修改后又出现zsh: trace trap错误。作为C语言新手,可能忽略了一些基础问题,以下是原始代码、输入情况及问题详情:
原始代码
#include <stdlib.h> #include <stdio.h> #include <string.h> void createAndBootQcow2(char size) { char img[500]; printf("Enter Image path: "); scanf("%s", img); char command_string_1[200]; char command_string[200]; strcpy(command_string_1, "qemu-img create -f "); strcpy(command_string, &size); strcat(command_string_1, command_string); //printf("%s", command_string); system(command_string); }; void main() { char option; printf("--------------\n"); printf("-QEMU Manager-\n"); printf("--------------\n"); printf("Options\n"); printf("1. Create qcow2 image and boot from iso\n"); printf("2. Create raw image and boot from iso\n"); printf("3. Create VMDK image and boot from iso\n"); printf("4. Boot from selected image file\n"); printf("5. Boot from configuration\n"); scanf("%c", &option); char size[3]; switch (option) { case '1': printf("Enter Virtual Hard Disk Size: "); scanf("%s", &size); createAndBootQcow2(&size); break; case '2': //createAndBootRaw(); break; case '3' : //createAndBootVmdk(); break; case '4' : //bootFromImage(); break; case '5' : //loadLocalConfigAndBoot(); break; }; }
问题场景
输入内容为:Enter Virtual Hard Disk Size: 50G,原本期望程序进入createAndBootQcow2()函数,但实际触发段错误。后续修改代码时:
- 编辑1:更新后出现
zsh trace trap错误 - 编辑2:将img和size改为字符串类型,仍出现
zsh: trace trap,错误位置在createAndBootQcow2()函数内 - 编辑3:调整代码以调用
system(command_string)执行qemu-img,错误依旧发生在createAndBootQcow2()函数内
核心问题分析
- 参数类型完全不匹配:
createAndBootQcow2定义的参数是char size,但调用时传入的是&size(char数组的地址,类型为char**),直接导致内存访问越界。 - 字符串缓冲区溢出:
main中定义char size[3],输入"50G"需要3个字符加终止符'\0',数组空间不足,会破坏相邻内存。 - strcpy使用错误:
strcpy(command_string, &size)中,&size是单个char的地址,不是以'\0'结尾的合法字符串,strcpy会持续读取内存直到找到终止符,触发段错误。 - 命令拼接逻辑错误:代码中最终调用
system(command_string),但command_string仅存储了size的内容,不是完整的qemu-img命令,执行逻辑完全错误。 - scanf读取空白字符问题:
scanf("%c", &option)会读取输入选项后的换行符,导致后续输入处理异常。 - 不规范的main函数:标准C中
main函数应为int main(),而非void main()。
解决思路与修正代码
关键修正点
- 统一用字符串类型处理磁盘大小,函数参数改为
const char* - 用
snprintf替代strcpy+strcat,安全拼接命令,避免缓冲区溢出 - 增大数组容量,确保能容纳输入内容与终止符
- 限制
scanf读取长度,防止溢出 - 修正参数传递方式,直接传递数组名(退化为指针)
- 修复
scanf读取空白字符的问题,确保选项输入正确 - 补全qemu-img命令的完整逻辑(格式、镜像路径、大小)
修正后代码
#include <stdlib.h> #include <stdio.h> #include <string.h> void createAndBootQcow2(const char* size) { char img[500]; printf("Enter Image path: "); // 限制读取长度,避免缓冲区溢出 scanf("%499s", img); // 用足够大的数组存储完整命令,也可动态分配内存 char command[1024]; // 拼接完整的qemu-img命令:格式为qcow2,指定镜像路径和大小 snprintf(command, sizeof(command), "qemu-img create -f qcow2 %s %s", img, size); printf("执行命令:%s\n", command); system(command); } int main() { char option; printf("--------------\n"); printf("-QEMU Manager-\n"); printf("--------------\n"); printf("Options\n"); printf("1. Create qcow2 image and boot from iso\n"); printf("2. Create raw image and boot from iso\n"); printf("3. Create VMDK image and boot from iso\n"); printf("4. Boot from selected image file\n"); printf("5. Boot from configuration\n"); // 加空格跳过换行符等空白字符,确保读取到正确的选项 scanf(" %c", &option); // 增大数组容量,支持更长的大小字符串(如"100G") char size[10]; switch (option) { case '1': printf("Enter Virtual Hard Disk Size: "); // 限制读取长度,避免溢出 scanf("%9s", size); createAndBootQcow2(size); break; case '2': //createAndBootRaw(); break; case '3': //createAndBootVmdk(); break; case '4': //bootFromImage(); break; case '5': //loadLocalConfigAndBoot(); break; default: printf("无效选项\n"); }; return 0; }
内容的提问来源于stack exchange,提问作者Connor-Tozer
相关产品推荐
相关产品推荐

