メインコンテンツ

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

CERT C++: DCL54-CPP

割り当て関数と割り当て解除関数を同じスコープ内でペアとしてオーバーロード

説明

ルール定義

割り当て関数と割り当て解除関数は同じスコープ内でペアとしてオーバーロードします。1

Polyspace 実装

ルール チェッカーは、"割り当て関数または割り当て解除関数のオーバーロードが見つからない" をチェックします。

すべて展開する

問題

割り当て関数または割り当て解除関数のオーバーロードが見つかりませんは、operator new をオーバーロードしたが対応する operator delete をオーバーロードしていない場合 (またはその逆の場合) に発生します。

リスク

通常、空きストアのメモリの割り当てに加えて何らかのブックキーピングを実行するために operator new をオーバーロードします。対応する operator delete をオーバーロードしていない場合は、メモリの割り当てを解除するときに対応するブックキーピングを省略した可能性があります。

この欠陥もコーディング エラーを示す可能性があります。たとえば、operator new[] の配置形式をオーバーロードしたとします。

void *operator new[](std::size_t count, void *ptr);
次のように operator delete[] の非配置形式を使用してしまう場合があります。
void operator delete[](void *ptr);
この場合は次の配置形式でなければなりません。
void operator delete[](void *ptr, void *p );

修正方法

operator new をオーバーロードする際、対応する operator delete を同じスコープでオーバーロードしていることを確認します (その逆も同様)。

たとえば、あるクラス内で operator new の配置形式をオーバーロードするとします。

class MyClass {
   void* operator new  ( std::size_t count, void* ptr ){
   //...
   }
};
operator delete の配置形式もオーバーロードしていることを確認します。
class MyClass {
   void operator delete  ( void* ptr, void* place ){
   ...
   }
};

operator new に対応する operator delete を見つける方法については、operator new および operator delete のリファレンス ページを参照してください。

例 – オーバーロードされた operator newoperator delete の間の不一致
#include <new>
#include <cstdlib>

int global_store;

void update_bookkeeping(void *allocated_ptr, bool alloc) {
   if(alloc) 
      global_store++;
   else
      global_store--;
}


void *operator new(std::size_t size, const std::nothrow_t& tag);
void *operator new(std::size_t size, const std::nothrow_t& tag) { //Noncompliant
    void *ptr = (void*)malloc(size);
    if (ptr != nullptr)
        update_bookkeeping(ptr, true);
    return ptr;
}

void operator delete[](void *ptr, const std::nothrow_t& tag);
void operator delete[](void* ptr, const std::nothrow_t& tag) { //Noncompliant
    update_bookkeeping(ptr, false);
    free(ptr); 
}

この例では、演算子 operator new および operator delete[] はオーバーロードされていますが、対応する operator delete および operator new[] 演算子のオーバーロードがありません。

operator new のオーバーロードは、関数 update_bookkeeping を呼び出してグローバル変数 global_store の値を変更します。既定の operator delete が呼び出された場合、このグローバル変数は影響を受けませんが、これは開発者の想定に反する可能性があります。

修正 – operator delete の正しい形式をオーバーロード

operator new をオーバーロードする場合は、対応する形式の operator delete を同じスコープでオーバーロードします。

#include <new>
#include <cstdlib>

int global_store;

void update_bookkeeping(void *allocated_ptr, bool alloc) {
   if(alloc) 
      global_store++;
   else
      global_store--;
}


void *operator new(std::size_t size, const std::nothrow_t& tag);
void *operator new(std::size_t size, const std::nothrow_t& tag) {
    void *ptr = (void*)malloc(size);
    if (ptr != nullptr)
        update_bookkeeping(ptr, true);
    return ptr;
}

void operator delete(void *ptr, const std::nothrow_t& tag);
void operator delete(void* ptr, const std::nothrow_t& tag) {
    update_bookkeeping(ptr, false);
    free(ptr); 
}

チェック情報

グループ: 01.宣言と初期化 (DCL)

バージョン履歴

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.