メインコンテンツ

CERT C: Rule WIN30-C

割り当て関数と割り当て解除関数を適切にペアにする

説明

ルール定義

割り当て関数と割り当て解除関数を適切にペアにします。1

Polyspace 実装

ルール チェッカーは、"Windows での関数 alloc と関数 dealloc の不一致" をチェックします。

すべて展開する

問題

Windows での関数 alloc と関数 dealloc の不一致は、使用する Windows® 割り当て解除関数とそれに対応する割り当て関数の組み合わせが不適切な場合に発生します。

リスク

割り当て関数に対応しない関数でメモリの割り当てを解除すると、メモリ破損または未定義の動作が発生する可能性があります。旧バージョンの Windows を使用している場合、不適切な関数を使用すると、新しいバージョンとの互換性の問題が発生する可能性もあります。

修正方法

次の表に示された関数に従って、割り当て関数と割り当て解除関数を適切に組み合わせます。

割り当て関数割り当て解除関数
malloc()free()
realloc()free()
calloc()free()
_aligned_malloc()_aligned_free()
_aligned_offset_malloc()_aligned_free()
_aligned_realloc()_aligned_free()
_aligned_offset_realloc()_aligned_free()
_aligned_recalloc()_aligned_free()
_aligned_offset_recalloc()_aligned_free()
_malloca()_freea()
LocalAlloc()LocalFree()
LocalReAlloc()LocalFree()
GlobalAlloc()GlobalFree()
GlobalReAlloc()GlobalFree()
VirtualAlloc()VirtualFree()
VirtualAllocEx()VirtualFreeEx()
VirtualAllocExNuma()VirtualFreeEx()
HeapAlloc()HeapFree()
HeapReAlloc()HeapFree()

例 - 不適切な関数によって割り当て解除されたメモリ
#ifdef _WIN32_
#include <windows.h>
#else
#define _WIN32_
typedef void *HANDLE;
typedef HANDLE HGLOBAL;
typedef HANDLE HLOCAL;
typedef unsigned int UINT;
extern HLOCAL LocalAlloc(UINT uFlags, UINT uBytes);
extern HLOCAL LocalFree(HLOCAL hMem);
extern HGLOBAL GlobalFree(HGLOBAL hMem);
#endif

#define SIZE9 9


void func(void)
{
	/* Memory allocation */
    HLOCAL p = LocalAlloc(0x0000, SIZE9);
	
    if (p) {
		/* Memory deallocation. */
        GlobalFree(p); //Noncompliant
		
    }
}
     
      

この例では、LocallAlloc() によってメモリが割り当てられています。その後、プログラムでは、間違って GlobalFree() を使用してメモリの割り当てを解除しています。

修正 — Windows の割り当て関数と割り当て解除関数を適切に組み合わせる

LocalAllocate() を使用してメモリを割り当てた場合は、LocalFree() を使用してメモリの割り当てを解除します。

#ifdef _WIN32_
#include <windows.h>
#else
#define _WIN32_
typedef void *HANDLE;
typedef HANDLE HGLOBAL;
typedef HANDLE HLOCAL;
typedef unsigned int UINT;
extern HLOCAL LocalAlloc(UINT uFlags, UINT uBytes);
extern HLOCAL LocalFree(HLOCAL hMem);
extern HGLOBAL GlobalFree(HGLOBAL hMem);
#endif

#define SIZE9 9
void func(void)
{
	/* Memory allocation */
    HLOCAL p = LocalAlloc(0x0000, SIZE9);
    if (p) {
		/* Memory deallocation. */
        LocalFree(p);  
    }
} 

チェック情報

グループ: Rule 51.Microsoft Windows (WIN)

バージョン履歴

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.