1

I use Linux only but I want to understand what this means:

From the Linux Programming Interface:

Blocks of memory allocated using memalign() or posix_memalign() should be deallocated with free().

On some UNIX implementations, it is not possible to call free() on a block of memory allocated via memalign(), because the memalign() implementation uses malloc() to allocate a block of memory, and then returns a pointer to an address with a suitable alignment in that block. The glibc implementation of memalign() doesn’t suffer this limitation.

From man memalign:

POSIX requires that memory obtained from posix_memalign() can be freed using free(3). Some systems provide no way to reclaim memory allocated with memalign() or valloc() (because one can pass to free(3) only a pointer obtained from malloc(3), while, for example, memalign() would call malloc(3) and then align the obtained value). The glibc implementation allows memory obtained from any of these functions to be reclaimed with free(3).

I don't know much about memory alignment and don't understand on "for example, memalign() would call malloc(3) and then align the obtained value".

Could someone tell me what's going on here and what could be wrong with free()?

0

1 Answer 1

2

Only posix_memalign should be used since it's defined by POSIX, as its name suggests. For issues with memalign see for example the Solaris 10 manual page for memory allocation functions:

The argument to free() is a pointer to a block previously allocated by malloc(), calloc(), or realloc(). After free() is executed, this space is made available for further allocation by the application, though not returned to the system. Memory is returned to the system only upon termination of the application. If ptr is a null pointer, no action occurs. If a random number is passed to free(), the results are undefined.

The description of free() doesn't even mention memalign allocations.

for example, memalign() would call malloc(3) and then align the obtained value

The following implementation is an example of the given description:

void *memalign(size_t alignment, size_t size)
{
    void *mem;
    uintptr_t uip_mem, uip_align;

    // fail if alignment is smaller than sizeof(void*) or not a power of two
    if (alignment < sizeof(void*) || alignment & (alignment - 1)) {
        errno = EINVAL;
        return NULL;
    }

    // allocate alignment extra bytes to prevent heap overflow
    mem = malloc(size + alignment);
    if (mem == NULL)
        return NULL;

    uip_mem = (uintptr_t) mem;
    uip_align = (uintptr_t) alignment;

    // align up returned address
    return (void*) ((uip_mem + uip_align - 1) & -uip_align);
}

See this Wikipedia page for more information about alignment. The previous implementation may or may not return the same address returned by malloc, depending on its alignment. Since the returned address may not be the exact same returned by a malloc call, it cannot safely be passed to free, as it expects an unchanged value returned by malloc (or other allocation function).

1
  • How "The glibc implementation allows memory obtained from any of these functions to be reclaimed with free(3)" ?
    – Rick
    Commented Sep 16, 2022 at 15:27

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .