一、问题引入
程序是由许多个函数组成的,而编写一个好的、安全的函数是很重要的。
随笔通过引用 #include <stdio.h>
库中的两个函数来分析:sprintf() 和 snprintf(),为什么一个好的、安全的函数的那么的重要?
二、解决过程
- sprintf函数例子
#include <stdio.h>
#include <string.h>
int main(void)
{
char buf[5] = {0};
int len = 0;
sprintf(buf, "%s", "hello world");
len = strlen(buf);
printf("%s(%d Byte)\n", buf, len);
return 0;
}
编译、运行:
很明显,buf存放字符串最大有效字符数量为4 (最后一个字符位置,即buf[5]用于存放 \0
),但是运行结果不报错,还打印了一个非预期的结果。
预期的结果应为:hell
- snprintf函数例子
#include <stdio.h>
#include <string.h>
int main(void)
{
char buf[5] = {0};
int len = 0;
snprintf(buf, sizeof(buf), "%s", "hello world");
len = strlen(buf);
printf("%s(%d Byte)\n", buf, len);
return 0;
}
编译、运行:
尽管给定 hello world
,但snprintf函数会截断超出 sizeof(buf)-1
个字符,才能得到出符合预期的结果。
三、反思总结
对于函数的参数(作为输出)为数组的首地址(即一个指针),那么在接下来的参数应明确给出数组的最大长度,避免指针越界操作。
引申:若函数的参数为一个指针(作为输入),且不希望函数对通过该指针修改值的内容,在函数定义时,应对指针进行 const
限定。
四、参考引用
无