Main Content

Alignment changed after memory reallocation

Memory reallocation changes the originally stricter alignment of an object

Description

This defect occurs when you use realloc() to modify the size of objects with strict memory alignment requirements.

Risk

The pointer returned by realloc() can be suitably assigned to objects with less strict alignment requirements. A misaligned memory allocation can lead to buffer underflow or overflow, an illegally dereferenced pointer, or access to arbitrary memory locations. In processors that support misaligned memory, the allocation impacts the performance of the system.

Fix

To reallocate memory:

  1. Resize the memory block.

    • In Windows®, use _aligned_realloc() with the alignment argument used in _aligned_malloc() to allocate the original memory block.

    • In UNIX/Linux, use the same function with the same alignment argument used to allocate the original memory block.

  2. Copy the original content to the new memory block.

  3. Free the original memory block.

Note

This fix has implementation-defined behavior. The implementation might not support the requested memory alignment and can have additional constraints for the size of the new memory.

Examples

expand all

#include <stdio.h>
#include <stdlib.h>

#define SIZE1024 1024

void func(void)
{
    size_t resize = SIZE1024;
    size_t alignment = 1 << 12; /* 4096 bytes alignment */
    int *ptr = NULL;
    int *ptr1;

	/* Allocate memory with 4096 bytes alignment */
	
    if (posix_memalign((void **)&ptr, alignment, sizeof(int)) != 0) 
    {
        /* Handle error */      
	  }
	  
	/*Reallocate memory without using the original alignment. 
	ptr1 may not be 4096 bytes aligned. */
		
    ptr1 = (int *)realloc(ptr, sizeof(int) * resize);
	
    if (ptr1 == NULL)
    {
        /* Handle error */
    }

    /* Processing using ptr1 */

    /* Free before exit */
    free(ptr1);
}

        
      

In this example, the allocated memory is 4096-bytes aligned. realloc() then resizes the allocated memory. The new pointer ptr1 might not be 4096-bytes aligned.

Correction — Specify the Alignment for the Reallocated Memory

When you reallocate the memory, use posix_memalign() and pass the alignment argument that you used to allocate the original memory.

#include <stdio.h>
#include <stdlib.h>

#define SIZE1024 1024

void func(void)
{
    size_t resize = SIZE1024;
    size_t alignment = 1 << 12; /* 4096 bytes alignment */
    int *ptr = NULL;

	/* Allocate memory with 4096 bytes alignment */
    if (posix_memalign((void **)&ptr, alignment, sizeof(int)) != 0) 
    {
        /* Handle error */
    }
	
	/* Reallocate memory using the original alignment. */
    if (posix_memalign((void **)&ptr, alignment, sizeof(int) * resize) != 0) 
    {
        /* Handle error */
        free(ptr);
        ptr = NULL;
    }

    /* Processing using ptr */

    /* Free before exit */
    free(ptr);
}  

Result Information

Group: Dynamic memory
Language: C | C++
Default: On for handwritten code, off for generated code
Command-Line Syntax: ALIGNMENT_CHANGE
Impact: Low

Version History

Introduced in R2017b