我在C中编写了一些代码,它应该//p[@class='ch_title'][contains(.,'Tip')]/following-sibling::p[@class='ch_spec'][1]
一些输入数据到声明的缓冲区。这是代码:
<p class="ch_spec">Smartphone</p>
如果我现在运行二进制文件,我会假设超过11个输入参数的所有内容都会导致缓冲区溢出,但事实上它将我的输入附加到两个缓冲区:
strcpy
使用gdb检查变量也表明我的输入参数存储在两个缓冲区中:
#include <stdio.h>
#include <string.h>
void function(char *args) {
char buff_1[12];
char buff_2[3] = "ABC";
strcpy(buff_1, args);
printf("buff_1: %s \n", buff_1);
printf("buff_2: %s \n", buff_2);
}
int main(int argc, char *argv[]) {
printf("Input: ");
if(argc > 1)
function(argv[1]);
return 0;
}
我使用以下命令编译代码:./main (perl -e 'print "A"x15')
buff_1: AAAAAAAAAAAAAAA
buff_2 :ABCAAAAAAAAAAAAAAA
使用(gdb) x/1s buff_1
0xffffd284: 'A' <repeats 11 times>
(gdb) x/1s buff_2
0xffffd281: "ABC", 'A' <repeats 11 times>
有人能解释一下这是怎么回事吗?
答案 0 :(得分:4)
buff_2
没有足够的空间来终止空终止。因此printf("buff_2: %s \n", buff_2);
将溢出缓冲区,导致未定义的行为。
char buff_2[3] = "ABC"; // Not enough space for \0
char buff_2[4] = "ABC"; // OK
char buff_2[] = "ABC"; // OK, Size will be 4
答案 1 :(得分:3)
将更多字符写入缓冲区而不是空间调用未定义的行为。没有可预测的结果;当你这样做时,你不能假设任何事情。您不能期望总是得到确定的运行时错误。
这就是为什么你需要在将参数传递给strcpy
之前检查它的大小。没有这样做是一个错误。
作为旁注,您在此处有一个错误:char buff_2[3] = "ABC";
。空终止没有足够的空间。这意味着当您尝试打印该数组时,您将调用未定义的行为,因为它不是有效的,以null结尾的C字符串。