Does the pointer passed to free() have to point to beginning of the memory block, or can it point to the interior?

Deadly 提交于 2019-11-29 10:42:45

It has to point to the beginning of the block. It's safe to pass a null pointer to free(), but passing any pointer not allocated by malloc() or one of its relatives will cause undefined behaviour. Some systems will give you a runtime error - something along the lines of "Deallocation of a pointer not malloced".

Edit:

I wrote a test program to get the error message. On my machine, this program:

#include <stdlib.h>

int main(int argc, char **argv)
{
  int *x = malloc(12);
  x++;

  free(x);

  return 0;
}

Crashes with this message:

app(31550) malloc: *** error for object 0x100100084: pointer being freed was not allocated

The only thing you can pass to free is a pointer returned to you from malloc (or calloc, realloc, etc), or NULL.

I'm guessing you're asking because you have some function where you do a malloc, and you want to mess with the data block and then get rid of it when you're done, and you don't want to be bothered keeping a copy of the original pointer around. It doesn't work that way.

From the comments you have added to existing answers, it seems you are asking the wrong question. If memory alignment is what you need, why don't you ask that question? Ask about the root problem rather than asking about your perceive solution!

So if you don't mind I'll answer the question you should have asked:

Aligned memory allocation is supported in Win32 by _aligned_malloc(). It is more of less equivalent to POSIX memalign()

If you need an implementation of aligned allocation, it is fairly simple to implement:

void* aligned_malloc( size_t size, size_t alignment )
{
    void* unaligned = malloc( size + alignment ) ;
    void* aligned = (void*)(((intptr_t)unaligned + alignment) & ~(alignment - 1));
    void** free_rec_ptr = ((void**)aligned - 1) ;
    *free_rec_ptr = unaligned ;

    return aligned ;
}

void aligned_free( void* block )
{
    void** free_rec_ptr = ((void**)block - 1) ;
    free( *free_rec_ptr ) ;
}

The alignment argument must be a power of two.

FWIW, the last time I looked into how the C run time library worked with malloc and free, the block that malloc gives you actually has some extra words at negative offsets relative to the pointer it gives you. These say things like how big the block is, and other stuff. free relied on being able to find those things. Don't know if that sheds any light.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!