C语言函数安全性规范:sprintf()和snprintf()

发布时间 2023-06-07 15:24:35作者: eiSouthBoy

一、问题引入

程序是由许多个函数组成的,而编写一个好的、安全的函数是很重要的。

随笔通过引用 #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 限定。

四、参考引用