【问题标题】:No error even when I'm overriding the limit of allocated memory?即使我覆盖分配内存的限制也没有错误?
【发布时间】:2011-01-21 23:05:21
【问题描述】:

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

我不明白如何将 23 个字符放入一个被分配为 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;
}

【问题讨论】:

标签: c


【解决方案1】:

在 C 中溢出缓冲区时的行为是未定义的。所以任何事情都可能发生,包括什么也没有。具体来说,C 不是必需的,并且有意设计为不执行边界检查。

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

【讨论】:

    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

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

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

      【讨论】:

        【解决方案4】:

        您正在产生一个错误,但就像许多错误一样,它只是碰巧没有被注意到。仅此而已。

        这可能是由于以下几个原因之一 - 可能是免费存储的结构方式,分配之间存在松弛空间,因为系统需要(或想要)保持可分配块的地址在某些边界上对齐。因此,稍微超出分配的块的写入不会干扰空闲存储数据结构,但会更远一些。

        也很可能您的错误确实破坏了免费商店经理正在使用的某些东西,但它恰好没有在您的简单程序中实际使用,因此(还)没有注意到错误。

        【讨论】:

        • 澄清一下 - OP 可能用于更高级的语言,其中会捕获此类错误。 C 是故意不安全的,C 中的这种行为被标准称为“未定义行为”,这意味着代码可以为所欲为。大多数时候,它会做它所能做的最简单的事情,那就是忽略你不被允许写入该空间并无论如何都要这样做的事实。这就是 C 语言如此难的主要原因——当你做错事时,没有任何东西可以检查你。
        • 非常感谢您的回答。
        猜你喜欢
        • 1970-01-01
        • 2015-09-25
        • 1970-01-01
        • 2018-08-12
        • 2018-02-10
        • 2013-12-09
        • 1970-01-01
        • 2014-02-15
        • 1970-01-01
        相关资源
        最近更新 更多