reply
为S|[2 3 4 5 6 7 8 9]|[2 3 4 5 6 7 8 9]
char com[10], f[100], s[100];
sscanf(reply, "%[^!]|%[^!]|%[^!]", com, f, s);
它会导致堆栈粉碎。我知道sscanf通常是不安全的,但我想知道为什么它在这里失败了——当输入字符串很好的时候。
这里的输出:
*检测到堆栈粉碎*:/testClient已终止======回溯:=========/lib/i386-linux-gnu/libc.so.6(__defense_fail+0x50([0x1f5df0]/lib/i386-linux-gnu/libc.so.6(+0xe5d9a([0x1f5d9a]./testClient[0x804b336]/lib/i386 linux gnu/libc.so.6(__libc_start_main+0xe7([0x26e37]./testClient[0x804add1]
======内存映射:==========00110000-0026a000 r-xp 0000000008:01523281/lib/i386-linux-gnu/libc-2.13.so 00261000-0026b000--p0015a000 08:01 523281/lib/i386 linux gnu/libc-2.13.so0026b000-0026d000 r--p 0015a000 08:01 523281
/lib/i386 linux gnu/libc-2.13.so 0026d000-0026e000 rw-p 0015c000 08:01523281/lib/i386 linux gnu/libc-2.13.so 0026e00-00271000 rw-p00000000 00:00 0 0027100-00286000 r-xp 00000000 08:01 523299
/lib/i386 linux gnu/libpthread-2.13.3so 00286000-00287000 r--p 0001500008:01 523299/lib/i386 linux gnu/libpthread-2.13.so00287000-00288000 rw-p 00016000 08:01 523299
/lib/i386 linux gnu/libpthread-2.13.so 00288000-0028a000 rw-p 0000000000:00 0 003e8000-00404000 r-xp 00000000 08:01 523304
/lib/i386 linux gnu/ld-2.13.so 00404000-00405000 r--p 0001b000 08:01523304/lib/i386 linux gnu/ld-2.13.so 00405000-00406000 rw-p0001c000 08:01 523304/lib/i386 linux gnu/ld-2.13.so004c9000-004d0000 r-xp 00000000 08:01 523283
/lib/i386 linux gnu/librt-2.13.so 004d0000-004d1000 r--p 0000600008:01 523283/lib/i386 linux gnu/librt-2.13.so 004d1000-004d2000rw-p 00007000 08:01 523283/lib/i386 linux gnu/librt-2.13.so0053f000-00540000 r-xp 00000000 00:00 0[vdso]007c9000-007ed000 r-xp 00000000 08:01 523303
/lib/i386 linux gnu/libm-2.13.so 007ed000-007ee000 r--p 00023000 08:01523303/lib/i386 linux gnu/libm-2.13.so 007ee000-007ef000 rw-p00024000 08:01 523303/lib/i386 linux gnu/libm-2.13.so00ce00-00dcd000 r-xp 00000000 08:01 1051412
/usr/lib/i386 linux gnu/libstdc++.so.6.00.14 00dcd000-00dd1000 r--p000de000 08:01 1051412/usr/lib/i386 linux gnu/libstdc++.so.6.0.1400dd1000-00dd2000 rw-p 000e2000 08:01 1051412
/usr/lib/i386 linux gnu/libstdc++.so.6.00.14 00dd2000-00dd9000 rw-p00000000 00:00 00 e5100-00e53000 r-xp 00000000 08:01 1070941
/usr/lib/libboostrongystem.so.1.46.1 00e5300-00e54000 r--p 0000200008:01 1070941/usr/lib/librastrongystem.so.1.46.1 00e54400-00e55000rw-p 00003000 08:01 1070941/usr/lib/librustrongystem.so.1.46.100e9c000-00eb6000 r-xp 00000000 08:01 523308
/lib/i386 linux gnu/libgcc_s.so.1 00eb6000-00eb7000 r--p 0001900008:01 523308/lib/i386 linux gnu/libgcc_s.so.1 00eb7000-00eb8000rw-p 0001a000 08:01 523308/lib/i386 linux gnu/libgcc_s.so.10804800-08067000 r-xp 00000000 08:01 1591111
/home/alex/pj/cpp/testClient/bin/Debug/testClient 08067000-08068000r--p 0001e000 08:01 1591111
/home/alex/pj/cpp/testClient/bin/Debug/testClient 08068000-08069000rw-p 0001f000 08:01 1591111
/home/alex/pj/cpp/testClient/bin/Debug/testClient 09050000-09071000rw-p 00000000 00:00 0[堆]b78d9000-b78dd000 rw-p0000000000:00 0 b78ef000-b78f2000 rw-p 00000000 00:00 0 bfba9000-bfbca000rw-p 00000000 00:00 0[堆栈]
一个问题是,您有管道|
字符来分隔数据中的字符串,但您的sscanf()
格式会查找字符类[^!]
(除感叹号外的所有字符(。您还应该为字符类指定缓冲区的大小,并检查返回值:
char com[10], f[100], s[100];
if (sscanf(reply, "%9[^|]|%99[^|]|%99[^|]", com, f, s) != 3)
...format error...
注意9和99的用法;必须指定为终端null留出空间的大小。