メインコンテンツ

メモリの再割り当て後に変更されたアライメント

メモリの再割り当てによるオブジェクトの元の厳密なアライメントの変更

説明

この欠陥は、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
影響度: Low

バージョン履歴

R2017b で導入