sprintf 陷阱--Segmentation fault

来源:互联网 发布:交友app源码诱导 编辑:程序博客网 时间:2024/06/07 06:52

有时为了构造特定的字符串,我们经常会使用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

原创粉丝点击