什么可能导致此缓冲区溢出?

fud*_*din 3 c string buffer-overflow

您好我正在尝试编译以下代码,

#include <stdio.h>
#include <string.h>
int main()
{
int i;
char a[3] = {'1', '2', '3'},b[3] = {'3', '2', '1'};
strcpy(a,b);
for(i=0; i<3; i++)
printf("%s",a);
return 0;
}
Run Code Online (Sandbox Code Playgroud)

但我收到以下错误(Buffer Overflow)

*** buffer overflow detected ***: ./prog terminated
======= Backtrace: =========
/lib/libc.so.6(__fortify_fail+0x48)[0xb7653ae8]
/lib/libc.so.6[0xb7651b30]
/lib/libc.so.6(__strcpy_chk+0x44)[0xb7650e14]
./prog[0x80484c9]
./prog[0x80483c1]
======= Memory map: ========
Run Code Online (Sandbox Code Playgroud)

现在我没有得到导致缓冲区溢出的原因.有人可以帮我解决一下吗?谢谢你的加入.

Set*_*gie 11

这个:

char a[4] = {'1', '2', '3'},b[4] = {'3', '2', '1'};
Run Code Online (Sandbox Code Playgroud)

创建两个字符数组,分别包含字符串"123"和"321",但不以NULL结尾.按照惯例,C字符串必须以NULL结尾,否则操作它们的函数(例如strcpy)不知道它们的结束位置.您需要这样做以给它们NULL终止符:

char a[4] = {'1', '2', '3', 0}, b[4] = {'3', '2', '1', 0};
                            ^--------------------------^----> NULL terminators
                                                              (0 or '\0', NOT '0')
Run Code Online (Sandbox Code Playgroud)

另请注意,数组的大小从3更改为4以容纳结尾NULL.您还可以保留大小,让编译器通过查看初始化列表中放入的内容来确定生成数组的大小:

char a[] = {'1', '2', '3', 0}, b[] = {'3', '2', '1', 0}; // sizes are left out
Run Code Online (Sandbox Code Playgroud)

当您键入这样的字符串文字时:

char a[] = "hello";
Run Code Online (Sandbox Code Playgroud)

编译器最后会为你添加NULL,所以你真正做的是:

char a[] = "hello\0";
Run Code Online (Sandbox Code Playgroud)

这就是为什么在用双引号键入字符数组时不必这样做的原因.