使用malloc的宏内宏会导致运行时错误?

时间:2014-03-30 19:06:33

标签: c macros runtime-error libc

我有这段代码

#define MZERO(a, s)  (a==NULL ? NULL : memset(a, 0, sizeof(a)*s))
#define MALLOC(t)    (t*)malloc(sizeof(t))
#define CALLOC(t, s) s<=0 ? NULL : (t*)MZERO(calloc(sizeof(t), s), s)

基本上让我可以解决malloc等人需要的大量样板。 MALLOCMZERO按预期运行,但在运行时CALLOC会导致

malloc.c:3096: sYSMALLOc: Assertion `(old_top == (((mbinptr) (((char *)
&((av)->bins[((1) - 1) * 2]))- __builtin_offsetof (struct malloc_chunk, fd)))) &&
old_size == 0) || ((unsigned long) (old_size) >= (unsigned long)((((__builtin_offsetof
(struct malloc_chunk, fd_nextsize))+((2 * (sizeof(size_t))) - 1)) & ~((2 *
(sizeof(size_t))) - 1))) && ((old_top)->size & 0x1) && ((unsigned long)old_end &
pagemask) == 0)' failed.

我一直在他们的&#34;简单&#34;中使用这些宏。格式,如MALLOC,最近决定将它们组合在一起。请注意,即使没有三元运算符,也会出现相同的错误。

我发现的错误消息的唯一引用是一些mailing list个帖子,它们不包含解决方案。我想我过去没有遇到任何问题,但是我并不确定。无论如何,我的libgc版本为2.13-38+deb7u1,其中包含GCC 4.7.2

知道发生了什么事吗?

2 个答案:

答案 0 :(得分:1)

是的,当程序有一些内存损坏情况时,会出现这样的断言消息。您可能想要使用Valgrind。你的CALLOC MACRO也是不正确的,因为它实际上是清理内存两次所以它应该是

#define CALLOC(t, s) s<=0 ? NULL : (t*)MZERO(calloc(sizeof(t), s), s)

应该是

   #define CALLOC(t, s) s<=0 ? NULL : (t*)calloc(sizeof(*t), s)

答案 1 :(得分:1)

基本上,不要使用这样的宏。你刚刚进入一个痛苦的世界。

记住宏是由预处理器执行的文本扩展。让我们假装我们是预处理器,你的两个宏......

#define MZERO(a, s)  (a==NULL ? NULL : memset(a, 0, sizeof(a)*s))
#define CALLOC(t, s) s<=0 ? NULL : (t*)MZERO(calloc(sizeof(t), s), s)

现在,MZERO(calloc(sizeof(t), s), s)部分会像这样展开: -

(calloc(sizeof(t), s)==NULL ? NULL : memset(calloc(sizeof(t), s), 0, sizeof(calloc(sizeof(t), s))*s))

我认为你真的不想要calloc三次被召唤。我可以列出一些其他潜在的问题,因为你没有正确地将每个参数包装在宏中的括号中,但实际上,足够:不要滥用这样的宏。