即使我超越分配的内存限制也没有错误?

时间:2010-02-28 06:43:05

标签: c

我可能是愚蠢的,在这种情况下你需要原谅我......但我不明白这一点。 我正在分配一个16个字符的缓冲区,然后(在一个for循环中)放入23个(!?)随机字符然后打印出来。

我没有得到的是如何将23个字符放入一个malloc为16个字符的缓冲区中...当我将循环更改为24个字符时,我得到一个错误(至少在Linux中使用gcc) )...但为什么不“更早”(17个字符应该打破它......不?)

这是我的示例代码:

#include <stdio.h>
#include <stdlib.h>

int main()
{
    int n;
    char *buf;

    buf = malloc(16 * sizeof(*buf));
    if(buf == NULL) exit(1);

    for(n = 0; n < 22; n++)
    {
        buf[n] = rand()%26+'a';
    }
    buf[n]='\0';

    printf("Random string: %s\n", buf);

    free(buf);
    buf = NULL;

    getchar();
    return 0;
}

4 个答案:

答案 0 :(得分:6)

您正在产生错误,但是就像许多错误一样,它恰好不会被注意到。这就是它的全部内容。

这可能是出于以下几个原因之一 - 可能是免费存储的结构方式,分配之间存在松弛的空间,因为系统需要(或希望)保持可分配块的地址在某些边界上对齐。因此,稍微写一下你分配的块不要干扰免费存储数据结构,但是它们可以进一步干预它们。

你的bug很可能破坏了免费商店经理正在使用的东西,但它恰好在你的简单程序中没有被实际使用,所以错误没有被发现(还)。

答案 1 :(得分:3)

大多数内存分配策略将malloc请求四舍五入到一些量化值。通常是16或32个字节。该量化通常在分配器添加其开销(用于跟踪已分配的块)之后发生,因此通常会发现您可以通过少量字节溢出malloc,而不会对堆造成任何实际损坏,尤其是当分配大小是奇数时。

当然,这不是您想要依赖的东西,它是c运行时库的实现细节,如有更改,恕不另行通知。

答案 2 :(得分:1)

在C中溢出缓冲区时的行为未定义。所以任何事都可能发生,包括什特别是C不是必需的,故意设计不执行边界检查。

如果您遇到任何运行时错误,通常是因为它已被操作系统检测和捕获,而不是由C运行时检测和捕获。只有当访问侵入未映射到进程的内存时,才会发生这种情况。更常见的是,它只会访问属于您的进程但可能被其他内存对象使用的内存;然后,程序的行为将取决于您的代码对无效数据的作用。

答案 3 :(得分:0)

在C中你会逃脱这些事情。稍后,程序的其他部分可能会进入并覆盖您不应使用的区域。所以最好不要测试这些东西。