Alignment changed after memory reallocation

Перераспределение памяти изменяет первоначально более строгое выравнивание объекта

Описание

Этот дефект возникает, когда вы используете realloc() для изменения размера объектов со строгими требованиями к выравниванию памяти.

Риск

Указатель возвращен realloc() могут быть соответственно назначены объектам с менее строгими требованиями к выравниванию. Несогласованное выделение памяти может привести к нижнему потоку буфера или переполнению, незаконно удаленному указателю или доступу к произвольным местоположениям памяти. В процессорах, поддерживающих несогласованную память, выделение ресурсов влияет на эффективность системы.

Зафиксировать

Для перераспределения памяти:

  1. Измените размер блока памяти.

    • В Windows®, использовать _aligned_realloc() с аргументом выравнивания, используемым в _aligned_malloc() для выделения исходного блока памяти.

    • В UNIX/Linux используйте ту же функцию с тем же аргументом выравнивания, используемым для выделения исходного блока памяти.

  2. Скопируйте исходное содержимое в новый блок памяти.

  3. Освободите исходный блок памяти.

Примечание

Это исправление имеет поведение, определяемое реализацией. Реализация может не поддерживать требуемое выравнивание памяти и может иметь дополнительные ограничения на размер новой памяти.

Примеры

расширить все

#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);
}

        
      

В этом примере выделенная память выровнена на 4096 байт. realloc() затем изменяет размер выделенной памяти. Новый указатель ptr1 не может быть выровнено на 4096 байт.

Коррекция - задайте выравнивание для перераспределенной памяти

Когда вы перераспределяете память, используйте posix_memalign() и передайте аргумент выравнивания, который вы использовали для выделения исходной памяти.

#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);
}  

Информация о результатах

Группа: Динамическая память
Язык: C | C++
По умолчанию: On для рукописного кода, off для сгенерированного кода
Синтаксис командной строки : ALIGNMENT_CHANGE
Влияние: Низкое
Введенный в R2017b