越界写作并不总是导致错误

时间:2018-03-13 20:41:46

标签: c memory malloc

我写了一个函数来添加项目到我的日志文件。变量loglevs[]des一起超过30个字符(到目前为止)。当我使用下面的功能时,一切正常。

char *logitem (int loglev, const char *des) {

    extern const char *loglevs[];
    char *lld; // loglevel & description total 28 characters (7+1+20)

    lld = (char *) malloc((29) * sizeof(char));
    snprintf(lld, 29, "[%5s] %s", loglevs[loglev], des);

    return lld;

}

但是当我使用malloc(24)代替malloc(29)时,我收到以下错误:

root@vm:/home/geohei/devel# prog
*** Error in `prog': malloc(): memory corruption: 0x0000000000853330 ***
Aborted (core dumped)

我原本希望在malloc(28)处收到错误。为什么它只显示在malloc(24)?实际上,我可以在弹出错误之前前往malloc(25)

我多次确认了测试。

3 个答案:

答案 0 :(得分:4)

这是未定义的行为,在此online c standard draft中定义如下:

  

<强> 3.4.3

     

1未定义的行为行为,使用不可移植或错误的行为   程序构造或错误数据,本国际   标准没有要求

     

2注意可能的未定义行为包括忽略这种情况   完全具有不可预测的结果,在翻译过程中表现出色   或者以文件化的方式执行程序   环境(有或没有发出诊断信息),到   终止翻译或执行(发布a   诊断信息)。

所以程序可以做任何事情,甚至忽略这种情况。但它也可能会崩溃或报警: - )

答案 1 :(得分:3)

undefined behavior。是UB的scaredmalloc只是一个标准的库例程(使用pages之类的system call来向内核询问内存(在mmap(2)的多个内容中)。如果“溢出”内存区域,则可能已损坏堆内存。

但请考虑使用valgrind(和address sanitizers等工具 - 例如with GCC)。

答案 2 :(得分:2)

如果你问为什么,有很多理由可以解释为什么会这样。它们取决于实施。

您的malloc函数可能会在固定大小的幕后分配内存,或者它可以分配已经四舍五入到某个值的内存。让我们举个例子说,你的malloc实现总是以8个字节的倍数分配。

然后,你的malloc(25) - malloc(29)调用实际上可能正在分配32个字节。所以超越结束,可能不会伤害到你。当你下到malloc(24)时,你可能会在内存块的末尾。

我们只能猜测这里发生了什么。该库可以在语言规范的范围内随意进行。

如上所述,此处的行为完全未定义,这就是您不应该这样做的原因。不同的库可能会产生完全不同的结果。