C语言scanf读取文件名与字面量相等但函数调用异常原因咨询
问题核心原因
你声明的char * filename仅为一个字符指针变量,没有为其分配合法的可写入内存空间,属于野指针,后续通过scanf向该指针指向的地址写入字符串的操作属于非法内存访问,触发了C语言标准中的「未定义行为」。
为什么字符串对比结果相等但传参后运行异常
未定义行为不代表程序一定会立刻崩溃,在你的测试场景下,野指针刚好指向了一块暂时未被其他程序逻辑占用的可用内存,写入的字符串暂时没有被破坏,因此strcmp对比时能得到相等的结果。但这块内存的所有权并不归属你的filename指针,在程序后续执行流程中(比如进入f函数后触发栈操作、系统内存调度),这块内存的内容很可能被其他逻辑篡改,或者系统触发非法访问拦截,自然就会出现运行异常。
直接传入字面量"grille1.txt"可以正常运行的原因是:字符串字面量在程序编译阶段就会被分配到静态只读存储区,内存空间合法、内容固定,指针指向的地址完全有效,所以调用不会出现问题。
修复方案
有两种常见的正确实现方式:
- 栈上分配固定长度的字符数组(适合文件名长度可控的场景)
// 声明足够容纳文件名的数组,256字节可覆盖绝大多数常规文件名场景 char filename[256]; // 限制scanf读取长度,避免缓冲区溢出,读取长度需比数组长度小1预留字符串结束符位置 scanf("%255s", filename); f(filename);
- 堆上动态分配内存(适合需要灵活控制内存生命周期的场景)
// 分配256字节的内存空间 char * filename = malloc(256); if (filename == NULL) { // 处理内存分配失败的异常逻辑 perror("内存分配失败"); return 1; } scanf("%255s", filename); f(filename); // 使用完成后释放内存,避免内存泄漏 free(filename);
内容的提问来源于stack exchange,提问作者Motcho
相关产品推荐
相关产品推荐

