循环中使用sprintf()触发Segmentation fault问题咨询
段错误产生原因
你的代码存在两个核心问题,其中野指针访问是直接触发段错误的根因:
- 未初始化野指针非法写入:你声明的
char* rounded_number只是一个字符指针变量,没有为它分配任何合法的可写内存(既没有指向提前定义的栈上字符数组,也没有通过malloc申请堆内存),属于指向随机地址的野指针。直接把它作为sprintf的写入目标缓冲区,是标准的未定义行为。
单次调用时不崩溃纯属概率事件:此时野指针刚好随机落到了程序可写的空闲内存区间,写入操作没有触发系统内存保护。进入for循环多次调用函数时,栈帧反复创建销毁、内存布局动态变化,野指针大概率会指向只读代码段、内核保护地址或其他非法访问区域,执行写入操作时就会直接触发Segmentation fault。 - sprintf参数传递错误:你写的
sprintf(rounded_number, "%.2e", rounded_number);第三个参数应该传入需要格式化的输入浮点数number,你传入了字符指针本身,就算指针内存合法,最终格式化出的内容也是完全错误的垃圾值,根本达不到四舍五入的效果。
修正后的参考实现
用栈上固定长度数组作为字符串缓冲区即可,不需要动态申请内存,避免内存泄漏:
#include <stdio.h> float rounding(float number) { // 32字节长度足够存储任意float类型转成的科学计数法字符串,留足冗余 char rounded_number[32]; float rounded; sprintf(rounded_number, "%.2e", number); sscanf(rounded_number, "%e", &rounded); return rounded; }
补充说明:通过sprintf/sscanf转字符串的方式做四舍五入执行效率很低,如果追求性能可以直接用数学运算实现:
roundf(number * 100) / 100.0f,使用时记得引入<math.h>头文件。
内容的提问来源于stack exchange,提问作者Sreenadha Saranga
相关产品推荐
相关产品推荐

