Search code examples
dynamic-arrays

Delete selected location from a set of contiguous memory locations


I ve the following memory allocation done
int *a;
a=malloc(5*sizeof(int));
Is there a way to just free say the 5th location of this set?

ie can I do free(a+4)??

Currently this gives a segmentation fault error.


Solution

  • No, you cannot do free(a+4) etc.

    Why? Because the C standard forbids it. You must pass the exact pointer returned by malloc() to free() without any pointer arithmetic.

    • http://www.kernel.org/doc/man-pages/online/pages/man3/free.3.html

      The free() function frees the memory space pointed to by ptr, which must have been returned by a previous call to malloc(), calloc() or realloc().

      • The Linux man pages are not the C standard itself but practically covers equivalent information on the C library functions.

    Why the standard forbids it? It is because some implementations of malloc() stores header information at the location a-4 (or wherever) and free() internally reads it by pointer arithmetic. If it's given a shifted pointer like a+4, it will miss the header info and get screwed. Cf.

    Incidentally some libc implementations provide non-standard functions which return the size of the allocated memory chunk:

    If you're curious how they're implemented and look into their source code, you often find that they read the header info at a-4 etc:

    OK, back to the original question. If you want to shorten (or lengthen) the memory chunk you allocated with malloc(), you can use realloc() as @Gustav said. But if you want to remove a few bytes from the middle of your memory chunk, you need manual re-allocation and copying. Actually realloc() might internally do a similar work, so be careful with the returned pointer which may be different from the original one.