C 复制到两个缓冲区中,尽管应该只填充一个缓冲区
C copies into two buffers though just one should be filled
我用 C 写了一些代码,应该 strcpy
一些输入数据到声明的缓冲区。这是代码:
#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;
}
如果我现在 运行 二进制文件,我会假设超过 11 个输入参数的所有内容都会导致缓冲区溢出,但实际上它会将我的输入附加到两个缓冲区:
./main (perl -e 'print "A"x15')
buff_1: AAAAAAAAAAAAAAA
buff_2 :ABCAAAAAAAAAAAAAAA
同时使用 gdb 检查变量显示我的输入参数存储在两个缓冲区中:
(gdb) x/1s buff_1
0xffffd284: 'A' <repeats 11 times>
(gdb) x/1s buff_2
0xffffd281: "ABC", 'A' <repeats 11 times>
我使用以下命令编译了代码:gcc -m32 -O0 -g -fno-stack-protector -o main main.c
使用 gcc (Ubuntu 5.2.1-22ubuntu2)
谁能解释一下这怎么可能?
您没有足够的 space 用于 buff_2
的空终止。所以 printf("buff_2: %s \n", buff_2);
会溢出你的缓冲区,导致 未定义的行为 。
char buff_2[3] = "ABC"; // Not enough space for [=10=]
char buff_2[4] = "ABC"; // OK
char buff_2[] = "ABC"; // OK, Size will be 4
向缓冲区写入比 space 更多的字符会调用未定义的行为。没有可预测的结果;当你这样做时,你不能假设任何事情。你不能指望总是得到确定性的 运行 时间错误。
这就是为什么您需要在将参数传递给 strcpy
之前检查参数的大小。不这样做是一个错误。
附带说明一下,您这里有一个错误:char buff_2[3] = "ABC";
。没有足够的空间用于空终止。这意味着当您尝试打印该数组时,您将调用未定义的行为,因为它不是有效的、以 null 结尾的 C 字符串。
我用 C 写了一些代码,应该 strcpy
一些输入数据到声明的缓冲区。这是代码:
#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;
}
如果我现在 运行 二进制文件,我会假设超过 11 个输入参数的所有内容都会导致缓冲区溢出,但实际上它会将我的输入附加到两个缓冲区:
./main (perl -e 'print "A"x15')
buff_1: AAAAAAAAAAAAAAA
buff_2 :ABCAAAAAAAAAAAAAAA
同时使用 gdb 检查变量显示我的输入参数存储在两个缓冲区中:
(gdb) x/1s buff_1
0xffffd284: 'A' <repeats 11 times>
(gdb) x/1s buff_2
0xffffd281: "ABC", 'A' <repeats 11 times>
我使用以下命令编译了代码:gcc -m32 -O0 -g -fno-stack-protector -o main main.c
使用 gcc (Ubuntu 5.2.1-22ubuntu2)
谁能解释一下这怎么可能?
您没有足够的 space 用于 buff_2
的空终止。所以 printf("buff_2: %s \n", buff_2);
会溢出你的缓冲区,导致 未定义的行为 。
char buff_2[3] = "ABC"; // Not enough space for [=10=]
char buff_2[4] = "ABC"; // OK
char buff_2[] = "ABC"; // OK, Size will be 4
向缓冲区写入比 space 更多的字符会调用未定义的行为。没有可预测的结果;当你这样做时,你不能假设任何事情。你不能指望总是得到确定性的 运行 时间错误。
这就是为什么您需要在将参数传递给 strcpy
之前检查参数的大小。不这样做是一个错误。
附带说明一下,您这里有一个错误:char buff_2[3] = "ABC";
。没有足够的空间用于空终止。这意味着当您尝试打印该数组时,您将调用未定义的行为,因为它不是有效的、以 null 结尾的 C 字符串。