我有这段代码
#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等人需要的大量样板。 MALLOC
和MZERO
按预期运行,但在运行时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
知道发生了什么事吗?
答案 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
三次被召唤。我可以列出一些其他潜在的问题,因为你没有正确地将每个参数包装在宏中的括号中,但实际上,足够:不要滥用这样的宏。