Question

I have this piece of code

#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)

which basicaly lets me get around the ridiculous amount of boilerplate C requires for malloc et al. MALLOC and MZERO run as intended however at runtime CALLOC causes

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.

I've been using these macros in their "simple" format, like MALLOC, and recently decided to combine them. Note that the same error appears even without the triadic operator.

The only references to that error message I've found are some mailing list posts which don't contain a solution. I think I've combined them in the past without any problems but I'm not really sure. In any case my libgc version is 2.13-38+deb7u1 with GCC 4.7.2

Any idea what's going on?

Was it helpful?

Solution

Basically, don't use macros like this. You're just entering a world of pain.

Remember macros are a text expansion performed by the pre-processor. Let's pretend we're the pre-processor, with two of your macros...

#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)

Now, the part MZERO(calloc(sizeof(t), s), s) will expand like this:-

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

I think you didn't really want calloc called three times. I can list a slew of other potential issues because you aren't correctly wrapping each param in brackets within the macros, but really, enough: Don't abuse macros like this.

OTHER TIPS

Yes, such asserts message would appear when the program has some memory corruption scenario. You may want to use Valgrind. Your CALLOC MACRO is also not correct in the sense it is actually clearing memory twice so it should be

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

should be

   #define CALLOC(t, s) s<=0 ? NULL : (t*)calloc(sizeof(*t), s)
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top