C函数内条件存储命令行变量报illegal instruction4错误如何解决
问题原因排查
1. 直接崩溃原因:非法写入只读内存
argv数组中存储的所有字符串都位于操作系统分配的只读存储区,你在main函数中把filename赋值为argv[1],相当于让filename指向了只读内存地址。后续在handleCommandLine中调用strcpy(filename, argv[2])时,本质是试图向只读内存写入数据,触发了内存访问异常,也就是你遇到的illegal instruction4报错。
2. 隐藏的逻辑错误:指针传值无法修改外层变量
你把filename作为参数传给handleCommandLine时走的是值传递,函数内部拿到的是filename指针的副本,哪怕你没有用strcpy、直接给filename赋值argv[2],函数执行结束后main里的filename也不会发生任何变化,完全达不到获取文件名的预期效果。
3. 参数校验缺失
当前代码完全没有校验argc的参数数量,比如你运行的命令是./test -v test abc.txt,实际传了3个参数,但你的设计预期最多只有2个参数,也会留下越界访问的隐患。
修复方案
修改后代码示例
#include <stdio.h> #include <stdbool.h> #include <string.h> void handleCommandLine(int argc, char *argv[], char **filename, bool *verbose) { // 先做参数数量校验 if (argc < 2) { printf("参数不足\n"); return; } if (strcmp(argv[1], "-v") == 0) { if (argc <3) { printf("缺少-v参数对应的文件名\n"); return; } printf("initialize\n"); *verbose = true; // 直接修改外层指针的指向,不需要拷贝字符串 *filename = argv[2]; } else { *verbose = false; *filename = argv[1]; } } int main(int argc, char *argv[]) { char *filename = NULL; bool verbose = false; // 传入argc和filename的指针地址 handleCommandLine(argc, argv, &filename, &verbose); if (filename != NULL) { printf("文件名:%s,是否开启verbose:%d\n", filename, verbose); } // 其余代码省略 return 0; }
修复点说明
- 把
filename的参数类型改为二级指针char**,直接修改外层main函数中filename的指向,不需要调用strcpy拷贝字符串,规避了只读内存写入的问题 - 新增了
argc参数校验,避免参数不足时的数组越界访问 - 不需要额外申请内存存储文件名,直接复用
argv中已经存在的字符串即可
内容的提问来源于stack exchange,提问作者David
相关产品推荐
相关产品推荐

