exponenta event banner

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