-1

I was writing a simple count inversion program using merge sort. While allocating the memory at runtime using calloc I got the following error:

a.out: malloc.c:2372: 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.
Aborted (core dumped)

with this code:

int *temp = (int*)calloc(1, sizeof(int) * (l1+l2)) ;

while using malloc instead of calloc works fine.On googling I found it a kind of memory corruption issue but didn't get it clearly

cbinder
  • 2,388
  • 2
  • 21
  • 36
  • works fine meant that you are able to use `temp` effectively? – Jack Oct 21 '14 at 13:09
  • 1
    In C++ don't use `calloc`, and in C [don't cast the return](http://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc). – Some programmer dude Oct 21 '14 at 13:10
  • 1
    Regarding the issue you're having, since you allocate zero bytes both [`malloc`](http://en.cppreference.com/w/c/memory/malloc) and [`calloc`](http://en.cppreference.com/w/c/memory/calloc) are allowed to return either `NULL` or a valid pointer (it's implementation defined). If you get a non-null pointer, all writes to the memory you "allocated" will be out of bounds, leading to [*undefined behavior*](http://en.wikipedia.org/wiki/Undefined_behavior). – Some programmer dude Oct 21 '14 at 13:14
  • I'm sorry it was 1 not 0 – cbinder Oct 21 '14 at 13:27
  • Changing `calloc(0, sizeof(int) * (l1+l2))` into `calloc(1, sizeof(int) * (l1+l2))` dramatically changes the question — doesn't it? Why are you doing the multiplication in the call rather than letting `calloc()` do it for you? It's a minor issue, though. Given the revised coding, you're trampling out of bounds, somewhere. The main difference is that `calloc()` zeroes memory by `malloc()` doesn't. You may be suffering from code that spots the zeroes as a null pointer and works differently. Is [`valgrind`](http://valgrind.org/) available for your platform? If so, use it. If not, get a VM. – Jonathan Leffler Oct 21 '14 at 13:34
  • hmm...getting it. BTW I wrote that by mistake.sorry for that – cbinder Oct 21 '14 at 13:37

2 Answers2

3
void* calloc(size_t num, size_t size);

This allocates a block num elements, each with size given by size. Since you pass 0 for num, you are asking to allocate a block of with zero elements. That's surely not what you intended and hence, somewhere down the line, you encounter an error.

I'm not sure what you are attempting to do. It looks like you are attempting to allocate an array of int with length l1+l2. In which case you need to write:

int *temp = calloc(l1+l2, sizeof *temp);

Note that I am assuming that you are writing C, and have removed the cast of the return value from calloc. If you are writing C++ then you would not be calling calloc in the first place. You'd be using std::vector<int>.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
1

Your calloc invocation doesn't seem very plausible to me. You are allocating zero items, each of which is sizeof(int) * (l1+l2) bytes in size.

That being said, I'm not sure whether an assertion is actually valid. The calloc documentation says:

void *calloc(size_t nelem, size_t elsize);

[…]

RETURN VALUE

Upon successful completion with both nelem and elsize non-zero, calloc() shall return a pointer to the allocated space. If either nelem or elsize is 0, then either a null pointer or a unique pointer value that can be successfully passed to free() shall be returned.

I.e. by this description I'd have expected that you get a pointer (possibly a null pointer) back which is not suitable for anything but being passed to free(). Maybe it's not actually the calloc call itself which fails but rather subsequent code which attempts to do something with the pointer?

Frerich Raabe
  • 90,689
  • 19
  • 115
  • 207
  • 1
    I'm puzzled that you expect a null pointer from `calloc(0, 0)` when the manual you quote explicitly says you _can_ get a non-null pointer back. The key point is that you cannot access any memory via the pointer that's returned, either because it is a null pointer or because it points to zero bytes of allocated memory. – Jonathan Leffler Oct 21 '14 at 13:27
  • 1
    By that description, I'd expect "either a null pointer or a unique pointer value". In the latter case, writing through it could easily cause heap corruption. – Mike Seymour Oct 21 '14 at 13:28
  • Oops, my thinking was ahead of my writing: indeed, I meant to write that you *can* get a null pointer back or a pointer which you can successfully pass to `free` (but not dereferencing let along writing through it). – Frerich Raabe Oct 21 '14 at 13:43