メインコンテンツ

AUTOSAR C++14 Rule A20-8-5

std::make_unique shall be used to construct objects owned by std::unique_ptr

説明

ルール定義

std::make_unique shall be used to construct objects owned by std::unique_ptr.

根拠

new 演算子を使用して、その結果得られる生のポインターを std::unique_ptr オブジェクトに変換することによってメモリを割り当てる代わりに、たとえば以下のようにします。

class numberClass {
   public:
     numberClass(int n): number(n){}
   private: 
     int number;
}
int aNumber=1; 
std::unique_ptr<numberClass> numberPtr (new numberClass(aNumber)); 
関数 std::make_unique を使用して、直接 std::unique_ptr オブジェクトを作成します。次に例を示します。
auto numberPtr = std::make_unique<numberClass>(aNumber);

以下の理由で std::make_unique を使用することを推奨します。

  • std::make_unique を使用した std::unique_ptr オブジェクトの作成は例外セーフです。そうしない場合、new 演算子を使用する動的メモリ割り当てとそれに続く変換の間で例外が発生する可能性があり、そうするとメモリ リークを招きます。例外でメモリ リークが引き起こされるのは特定のコンテキストの場合のみです。たとえば、std::unique_ptr オブジェクトが複数パラメーター関数の引数で作成され、もう一方の関数引数評価で例外がスローされる場合です。

  • より簡潔な構文を使用できます。動的に割り当てられるオブジェクトのデータ型を繰り返す必要はありません。

Polyspace 実装

チェッカーは、new 演算子から返された生のポインターからの std::unique_ptr オブジェクト (または boost::unique_ptr オブジェクト) の作成にフラグを設定します。

トラブルシューティング

ルール違反が想定されるものの、Polyspace® から報告されない場合は、コーディング規約違反が想定どおりに表示されない理由の診断を参照してください。

すべて展開する

#include <cstdint>
#include <string>

class Record {
    public:
       Record(std::string aName, std::string someInfo): name(aName), info(someInfo){       
       }
    private:
       std::string name;
       std::string info;
};

void addRecordToDataBase(std::unique_ptr<Record> aRecord, bool dataBaseIsFull);
bool checkDataBase(void); //Checks if database can accept more entries

void createRecord() {
    std::unique_ptr<Record> recordPtr1 (new Record("John", "Mechanic, New York")); //Noncompliant
    auto recordPtr2 = std::make_unique<Record>("Tom", "Plumber, Boston"); //Compliant
    
    addRecordToDataBase(std::unique_ptr<Record>(new Record("John", "Mechanic, New York")), checkDataBase()); //Noncompliant
    addRecordToDataBase(std::make_unique<Record>("Tom", "Plumber, Boston"), checkDataBase()); //Compliant
}

この例では、new 演算子が生のポインターを返し、それに続く変換によって生のポインターから std::unique_ptr オブジェクトが作成されるたびに、ルール違反になります。

addRecordToDatabase の最初の呼び出しでは、次のイベント シーケンスが発生する可能性があります (C++17 より前のバージョンの場合)。

  • 第 1 引数の評価。new 演算子によって Record オブジェクトのメモリが動的に割り当てられる。

  • 第 2 引数の評価。関数 checkDataBase が呼び出される。

  • 第 1 引数の評価の続き。new 演算子から取得された生のポインターが std::unique_ptr オブジェクトに変換される。

第 2 ステップで例外がスローされると、生のポインターはリソース管理オブジェクトに割り当てられず、その結果メモリ リークが発生します。

チェック情報

グループ: General utilities library
カテゴリ: Required、Automated

バージョン履歴

R2020b で導入

すべて展開する