メインコンテンツ

このページの内容は最新ではありません。最新版の英語を参照するには、ここをクリックします。

CERT C++: MEM36-C

realloc() を呼び出してオブジェクトのアライメントを変更しない

説明

ルール定義

realloc() を呼び出してオブジェクトのアライメントを変更しないようにします。1

Polyspace 実装

ルール チェッカーは、"メモリの再割り当て後に変更されたアライメント" をチェックします。

すべて展開する

問題

メモリの再割り当て後に変更されたアライメントは、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); //Noncompliant
	
    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);
}  

チェック情報

グループ: 06.メモリ管理 (MEM)

バージョン履歴

R2019a で導入


1 This software has been created by MathWorks incorporating portions of: the “SEI CERT-C Website,” © 2017 Carnegie Mellon University, the SEI CERT-C++ Web site © 2017 Carnegie Mellon University, ”SEI CERT C Coding Standard – Rules for Developing safe, Reliable and Secure systems – 2016 Edition,” © 2016 Carnegie Mellon University, and “SEI CERT C++ Coding Standard – Rules for Developing safe, Reliable and Secure systems in C++ – 2016 Edition” © 2016 Carnegie Mellon University, with special permission from its Software Engineering Institute.

ANY MATERIAL OF CARNEGIE MELLON UNIVERSITY AND/OR ITS SOFTWARE ENGINEERING INSTITUTE CONTAINED HEREIN IS FURNISHED ON AN "AS-IS" BASIS. CARNEGIE MELLON UNIVERSITY MAKES NO WARRANTIES OF ANY KIND, EITHER EXPRESSED OR IMPLIED, AS TO ANY MATTER INCLUDING, BUT NOT LIMITED TO, WARRANTY OF FITNESS FOR PURPOSE OR MERCHANTABILITY, EXCLUSIVITY, OR RESULTS OBTAINED FROM USE OF THE MATERIAL. CARNEGIE MELLON UNIVERSITY DOES NOT MAKE ANY WARRANTY OF ANY KIND WITH RESPECT TO FREEDOM FROM PATENT, TRADEMARK, OR COPYRIGHT INFRINGEMENT.

This software and associated documentation has not been reviewed nor is it endorsed by Carnegie Mellon University or its Software Engineering Institute.