exponenta event banner

Выравнивание изменено после перераспределения памяти

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

Описание

Этот дефект возникает при использовании 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++
По умолчанию: Вкл для рукописного кода, выкл для сгенерированного кода
Синтаксис командной строки: ALIGNMENT_CHANGE
Воздействие: Низкий
Представлен в R2017b