为什么malloc在两个不同的指针上调用相同的地址空间?

时间:2014-04-28 00:21:47

标签: c pointers malloc heap-corruption

下面的代码来自讨论堆溢出攻击的家庭作业,我将其理解为一个概念。我不明白的是与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

非常感谢。 :)

1 个答案:

答案 0 :(得分:4)

结果说明

buf1buf2未指向相​​同的空间。

您的结果可以解释如下。

幸运的是,分配给出了以下内存布局:

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}}