Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Do not invoke realloc() to modify the size of allocated storage objects that has have stricter alignment requirements than those normally provided guaranteed by malloc(). Storage allocated by a call to the standard aligned_alloc() function, for example, can have stricter than normal alignment requirements. The C standard mandates requires only that any a pointer returned by mallocrealloc() must be suitably aligned so that it may be assigned to a pointer to any type of object with a fundamental alignment requirement (storage allocated by a call to the C Standard aligned_alloc() function, for example.)

Noncompliant Code Example

This noncompliant code example returns a pointer to allocated memory that has been aligned to a 4096-byte boundary.  If the resize argument to the realloc() function is larger than the space object referenced by ptr, then realloc() will allocate new memory that is suitably aligned so that it may be assigned to a pointer to any type of object with a fundamental alignment requirement , but may not preserve the stricter alignment requirements of the original spaceobject.

Code Block
bgColor#ffcccc
langc
#include <stdlib.h>
 
void func(void) {
  size_t resize = 1024;
  size_t alignment = 1 << 12;
  int *ptr;
  int *ptr1;
  
  if (NULL == (ptr = (int *) aligned_alloc(alignment, sizeof(int))) == NULL) {
    /* Handle error */
  }

  if (NULL == (ptr1 = (int *) realloc(ptr, resize)) == NULL) {
    /* Handle error */
  }
}

...

This compliant solution  allocates resize bytes of new memory with the same alignment as the old memory, copies the original memory content, and then frees the old memory:. This solution has implementation-defined behavior because it depends on whether extended alignments in excess of _Alignof (max_align_t) are supported and the contexts in which they are supported. If not supported, the behavior of this compliant solution is undefined.

Code Block
bgColor#ccccff
langc
#include <stdlib.h>
#include <string.h>
 
void func(void) {
  size_t resize = 1024;
  size_t alignment = 1 << 12;
  int *ptr;
  int *ptr1;

  if (NULL == (ptr = (int *)aligned_alloc(alignment,
                                          sizeof(int))) == NULL) {
    /* Handle error */
  }

  if (NULL == (ptr1 = (int *)aligned_alloc(alignment,
                                           resize)) == NULL) {
    /* Handle error */
  }
  
  if (NULL == (memcpy(ptr1, ptr, sizeof(int)) == NULL) {
    /* Handle error */
  }
  
  free(ptr);
}

Compliant Solution (Windows)

Windows defines the _aligned_malloc() function to allocate memory on a specified alignment boundary.  The _aligned_realloc() [MSDN] can be used to change the size of this memory. This compliant solution demonstrates one such usage:

Code Block
bgColor#ccccff
langc
#include <malloc.h>
 
void func(void) {
  size_t alignment = 1 << 12;
  int *ptr;
  int *ptr1;
 
  /* Original allocation */
  if (NULL == (ptr = (int *)_aligned_malloc(sizeof(int), alignment))

                                           == NULLalignment))) {
    /* Handle error */
  }
 
  /* Reallocation */
  if (NULL == (ptr1 = (int *)_aligned_realloc(ptr, 1024, alignment))

                                             == NULLalignment))) {
    _aligned_free(ptr);
    /* Handle error */
  }

  _aligned_free(ptr1);
}

Note that the size the size and alignment arguments for _aligned_malloc() are provided in reverse order of the C Standard aligned_alloc() function.

...

Bibliography

[ISO/IEC 9899:2011Subclause  77.22.3.1, "The aligned_alloc Function"
[MSDN]aligned_malloc()

 

...