我写了一个函数来添加项目到我的日志文件。变量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)
。
我多次确认了测试。
答案 0 :(得分:4)
这是未定义的行为,在此online c standard draft中定义如下:
<强> 3.4.3 强>
1未定义的行为行为,使用不可移植或错误的行为 程序构造或错误数据,本国际 标准没有要求
2注意可能的未定义行为包括忽略这种情况 完全具有不可预测的结果,在翻译过程中表现出色 或者以文件化的方式执行程序 环境(有或没有发出诊断信息),到 终止翻译或执行(发布a 诊断信息)。
所以程序可以做任何事情,甚至忽略这种情况。但它也可能会崩溃或报警: - )
答案 1 :(得分:3)
是undefined behavior。是UB的scared。 malloc
只是一个标准的库例程(使用pages之类的system call来向内核询问内存(在mmap(2)的多个内容中)。如果“溢出”内存区域,则可能已损坏堆内存。
但请考虑使用valgrind(和address sanitizers等工具 - 例如with GCC)。
答案 2 :(得分:2)
如果你问为什么,有很多理由可以解释为什么会这样。它们取决于实施。
您的malloc函数可能会在固定大小的幕后分配内存,或者它可以分配已经四舍五入到某个值的内存。让我们举个例子说,你的malloc实现总是以8个字节的倍数分配。
然后,你的malloc(25) - malloc(29)调用实际上可能正在分配32个字节。所以超越结束,可能不会伤害到你。当你下到malloc(24)时,你可能会在内存块的末尾。
我们只能猜测这里发生了什么。该库可以在语言规范的范围内随意进行。
如上所述,此处的行为完全未定义,这就是您不应该这样做的原因。不同的库可能会产生完全不同的结果。