例子1:
#include <stdio.h> #include <stdlib.h> #include <string.h> int main(int argc, char** argv) { int i; char str[] = "This is a beautiful day!"; strcpy(str, "hello"); for (i = 0; i < sizeof(str) / sizeof(str[0]); i++) { printf("%c", str[i]); } printf("\n"); printf("%s\n", str); return 0; }
程序输出:
~ # ./a.out hellos a beautiful day! hello ~ #
(1)可以看到strcpy()拷贝了字符串中所有的内容,包括'\0'。
'\0'不仅仅是strcpy()的“监视卫兵”,而且也被拷贝进了目标字符串中。
例子2:
#include <stdio.h> #include <stdlib.h> #include <string.h> int main(int argc, char** argv) { char str1[] = "Work hard!"; char str2[] = "This is a beautiful day!"; strcpy(str1, str2); // 当目的字符串的缓冲区小于源字符串的缓冲区时 return 0; }
程序输出:
~ # ./a.out *** stack smashing detected ***: ./a.out terminated ======= Backtrace: ========= /lib/tls/i686/cmov/libc.so.6(__fortify_fail+0x50)[0xd01350] /lib/tls/i686/cmov/libc.so.6(+0xe22fa)[0xd012fa] ./a.out[0x80484dc] /lib/tls/i686/cmov/libc.so.6(__libc_start_main+0xe6)[0xc35bd6] ======= Memory map: ======== 00403000-0041e000 r-xp 00000000 08:01 261658 /lib/ld-2.11.1.so 0041e000-0041f000 r--p 0001a000 08:01 261658 /lib/ld-2.11.1.so 0041f000-00420000 rw-p 0001b000 08:01 261658 /lib/ld-2.11.1.so 004d9000-004da000 r-xp 00000000 00:00 0 [vdso] 00c1f000-00d72000 r-xp 00000000 08:01 266054 /lib/tls/i686/cmov/libc-2.11.1.so 00d72000-00d73000 ---p 00153000 08:01 266054 /lib/tls/i686/cmov/libc-2.11.1.so 00d73000-00d75000 r--p 00153000 08:01 266054 /lib/tls/i686/cmov/libc-2.11.1.so 00d75000-00d76000 rw-p 00155000 08:01 266054 /lib/tls/i686/cmov/libc-2.11.1.so 00d76000-00d79000 rw-p 00000000 00:00 0 00e5f000-00e7c000 r-xp 00000000 08:01 270893 /lib/libgcc_s.so.1 00e7c000-00e7d000 r--p 0001c000 08:01 270893 /lib/libgcc_s.so.1 00e7d000-00e7e000 rw-p 0001d000 08:01 270893 /lib/libgcc_s.so.1 08048000-08049000 r-xp 00000000 08:01 524474 /root/a.out 08049000-0804a000 r--p 00000000 08:01 524474 /root/a.out 0804a000-0804b000 rw-p 00001000 08:01 524474 /root/a.out 096ff000-09720000 rw-p 00000000 00:00 0 [heap] b76f3000-b76f4000 rw-p 00000000 00:00 0 b7703000-b7705000 rw-p 00000000 00:00 0 bfc15000-bfc2a000 rw-p 00000000 00:00 0 [stack] Aborted ~ #
(2)目的字符串缓冲区小于源的字符串缓冲区时,程序崩溃了。
例子3:
#include <stdio.h> #include <stdlib.h> #include <string.h> int main(int argc, char** argv) { char str1[] = "Work hard!"; char str2[] = {'H', 'e', 'l', 'l', 'o'}; strcpy(str1, str2); return 0; }
程序输出:
~ # ./a.out
Segmentation fault
~ #
(3)当源字符串“哨兵”的'\0'不存在时,程序也发生了崩溃。
总结:其实C语言库函数中存在着很多这种情况,需要我们在编程时注意。
下一篇介绍《C语言中的危险函数》特别的注意。