如果您在该调用之前执行其他操作,则您的堆栈区域将包含未使用的数据之外的其他数据。设想:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int use_stack(void) {
char str[500];
memset(str, 'X', sizeof(str));
printf("Filled memory from %p to %p.\n", &str, &str+sizeof str);
}
void print_stuff() {
int i;
char str[16]; // changed that so that 10..15 contain X
for(i = 0; i < 10; i++) {
str[i] = (char)(i+97);
}
printf("%s<END>",str); // have a line break before <END>? Then it comes from i.
printf("&str: %p\n", &str);
printf("&i: %p\n", &i);
// Here you see that i follows str as &i is &str + 16 (0x10 in hex)
}
int main() {
use_stack();
print_stuff();
}
您的堆栈区域将充满X
es 并printf()
会看到它们。
在您的情况和环境中,堆栈在程序启动时巧合地“干净”。
编辑:这可能会也可能不会发生。如果编译器将变量i
立即放在数组之后,您的数据仍然会被NUL
终止,因为第一个字节是i
(您碰巧打印的值 - 在您的情况下它可能是一个 libne 中断 - 而第二个字节是一个NUL
字节。即使是这种情况,您的代码也会调用 UB(未定义的行为)。
hexdump
如果你的输出包含一个0A
字符,你能看看(通过管道程序输出或类似的方法)吗?如果是这样,我的猜测是正确的。我刚刚测试了它,在我的编译器(gcc
)上似乎是这样。
如前所述,您不应该依赖任何东西。
EDIT2:如果您之前看到换行符<END>
,我的猜测是正确的。如果您查看现在正在打印的指针,您可以比较它们在内存中的地址。