下面的代码来自讨论堆溢出攻击的家庭作业,我将其理解为一个概念。我不明白的是与malloc及此代码示例中的指针完全相同的内容。显然两个指针都指向堆中的相同空间,但为什么会这样呢?不会为malloc保留buf1
的空间,然后为buf2
保留另一个空间吗?
int main(int argc, const char * argv[])
{
int diff, size = 8;
char *buf1, *buf2;
buf1 = (char * )malloc(size);
buf2 = (char *)malloc(size);
diff = buf2-buf1;
memset(buf2, '2', size);
printf("BEFORE: buf2 = %s",buf2);
memset(buf1, '1', diff +3);
printf("AFTER: buf2 = %s", buf2);
return 0;
}
此代码生成输出
BEFORE: buf2 = 22222222AFTER: buf2 = 11122222
非常感谢。 :)
答案 0 :(得分:4)
结果说明
buf1
和buf2
未指向相同的空间。
您的结果可以解释如下。
幸运的是,分配给出了以下内存布局:
buf1 buf2
|--------|--------|
第一个memset给出了
buf1 buf2
|--------|22222222|
,因为它从buf2的开始到结束为2。
第二个memset给出:
buf1 buf2
|11111111|11122222|
这是从buf1
开始到3结束时的设置。
未定义的行为
当您更改分配给程序的内存时,这不会出错。
但是以这种方式将buf2
传递给printf
会调用未定义的行为。
原因是printf
被认为是:
printf("BEFORE: buf2 = %s",buf2);
没有办法知道buf2
的大小,所以它一直持续到它看到你的代码没有添加的空值\0
字符。幸运的是,在buf2发生之后,你立即得到了值,这是空值。
您可以将\0
字符添加到buf2
的末尾。
或者在这种情况下更合适你可以使用精确格式说明符(.
int
后面的printf
)让printf("BEFORE: buf2 = %.8s",buf2);
知道要打印多少个字符。那将是这样做的:
{{1}}