有时为了构造特定的字符串,我们经常会使用sprintf函数。但是在linux中,该函数是不安全的。建议使用snprintf来指定写入的字节数。如下例所示:
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char* argv[])
{
char str[18];
int *pa = (int*)calloc(8, sizeof(int));
sprintf(str, "%s ++++++++++++++++++++++++++ %s", "hello", "world!!!!");
int n = printf("%s\n", u.str);
printf("%d characters.\n", n);
free(pa);
return 0;
}程序没有任何异常,str也能正常显示,最后顺利退出。但是我们已经很明显发现,其实str已经越界了。之所以没有出现异常是因为在str到pa之间的内存没有被使用,所以即使被非法写入,linux也无动于衷。但是危险却隐藏其中,时刻准备爆发。
如果我们的程序变成下面这样:
#include <stdlib.h>
#include <stdio.h>
struct unit
{
char str[18];
int* pa;
};
int main(int argc, char* argv[])
{
unit u;
u.pa = (int*)calloc(8, sizeof(int));
sprintf(u.str, "%s ++++++++++++++++++++++++++ %s", "hello", "world!!!!");
//snprintf(u.str, 8, "%s ++++++++++++++++++++++++++ %s", "hello", "world!!!!");
int n = printf("%s\n", u.str);
printf("%d characters.\n", n);
free(u.pa);
return 0;
}那么运行这个程序,我们就马上看到了Segmentation fault,该错误发生在free函数上。如果对于一个大型程序来说,这个错误就很难定位了。。
但是如果把sprintf换成snprintf则能有效避免这种事情发生。所以在linux编程中,要注意两件事情:
- 尽量少使用静态分配数组。如果使用了,一定要时刻注意越界问题
- 使用snprintf代替sprintf

本文通过两个示例展示了在Linux环境下使用sprintf函数可能导致的内存越界问题,并介绍了使用snprintf函数来替代以提高程序安全性。
890

被折叠的 条评论
为什么被折叠?



