【发布时间】:2016-06-22 12:43:31
【问题描述】:
我有以下 C 代码:
#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[]) {
int value = 5;
char buffer_one[8], buffer_two[8];
strcpy(buffer_one, "one"); /* Put "one" into buffer_one. */
strcpy(buffer_two, "two"); /* Put "two" into buffer_two. */
return 0;
}
根据我对堆栈的了解,buffer_one 数组应该从比 buffer_two 数组更高的地址开始,因为堆栈向着较低的地址增长,而 buffer_two 位于堆栈的顶部。但是,当我使用 gcc 编译代码并使用 GDB 单步执行代码时,它告诉我情况正好相反:
eman@eman:~/Documents/CFiles/bufferOverflow/source$ gcc -g -o example overflow_example.c
eman@eman:~/Documents/CFiles/bufferOverflow/source$ gdb -q example
Reading symbols from example...done.
(gdb) list
1 #include <stdio.h>
2 #include <string.h>
3 int main() {
4 char buffer_one[8];
5 char buffer_two[8];
6
7 strcpy(buffer_one, "one"); /* Put "one" into buffer_one. */
8 strcpy(buffer_two, "two"); /* Put "two" into buffer_two. */
9
10 return 0;
(gdb) break 9
Breakpoint 1 at 0x400571: file overflow_example.c, line 9.
(gdb) run
Starting program: /home/eman/Documents/CFiles/bufferOverflow/source/example
Breakpoint 1, main () at overflow_example.c:10
10 return 0;
(gdb) print &buffer_one
$1 = (char (*)[8]) 0x7fffffffdd50
(gdb) print &buffer_two
$2 = (char (*)[8]) 0x7fffffffdd60
(gdb)
这里发生了什么?
额外问题:为什么数组初始化为8字节,却占用了10字节?
【问题讨论】:
-
提示:不是 10 个字节,而是 0x10 个字节。
-
@Will 哦,16 个字节?我认为每个字符占用 1 个字节的内存而不是 2
-
很难说它是错的,因为没有正确的标准。
-
@Carefullcars,是什么让您认为存在堆栈?如果有一个堆栈,是什么让你认为它的增长方向是正确的?如果有堆栈,是什么让您认为函数的局部变量接收地址就好像它们按照声明的顺序被压入堆栈一样? 没有是 C 规定的。
-
假设一个底层 x64 架构,在你的例子中,gcc 编译器和一个基于 linux 的操作系统,堆栈是一个
reverse access数据映射。因此分配将向最高逻辑地址执行,访问将向最低逻辑地址执行。无论如何,据我所知,C 标准中没有堆栈的概念。