C6014

警告 C6014: メモリがリークしています。

この警告は、指定されたポインターが、解放されていない割り当て済みメモリまたは他の割り当て済みリソースを指していることを示しています。 アナライザーは、_Analysis_mode_(_Analysis_local_leak_checks_) SAL 注釈が指定されている場合にのみこの条件をチェックします。 既定では、この注釈は Windows カーネル モード (ドライバー) コードに対して指定されます。 SAL 注釈の詳細については、「SAL 注釈を使って C/C++ のコード障害を減らす方法」を参照してください。

この警告が発生するコード例を次に示します。

// cl.exe /analyze /EHsc /nologo /W4
#include <sal.h>
#include <stdlib.h>
#include <string.h>

_Analysis_mode_(_Analysis_local_leak_checks_)

#define ARRAYSIZE 10
const int TEST_DATA [ARRAYSIZE] = {10,20,30,40,50,60,70,80,90,100};

void f( )
{
    int *p = (int *)malloc(sizeof(int)*ARRAYSIZE);
    if (p) {
        memcpy(p, TEST_DATA, sizeof(int)*ARRAYSIZE);
        // code ...
    }
}

int main( )
{
    f();
}

次のコードでは、メモリを解放することで警告を修正します。

// cl.exe /analyze /EHsc /nologo /W4
#include <sal.h>
#include <stdlib.h>
#include <string.h>

_Analysis_mode_(_Analysis_local_leak_checks_)

#define ARRAYSIZE 10
const int TEST_DATA [ARRAYSIZE] = {10,20,30,40,50,60,70,80,90,100};

void f( )
{
    int *p = (int *)malloc(sizeof(int)*ARRAYSIZE);
    if (p) {
        memcpy(p, TEST_DATA, sizeof(int)*ARRAYSIZE);
        // code ...
        free(p);
    }
}

int main( )
{
    f();
}

この警告は、リソースが一般的に別の場所にエイリアス化されるときに、メモリおよびリソースのリークの両方について報告されます。 メモリは、_Out_ パラメーター注釈、グローバル変数、または戻り値を使用して、メモリへのポインターが関数をエスケープしたときにエイリアス化されます。 この警告は、引数が解放されると予期されるものとして注釈を付けられている場合に、関数の終了時に報告されることがあります。

なお Code Analysis は、メモリ アロケーターの実際の実装 (アドレス算術演算を伴う) を認識せず、メモリが割り当てられていることを認識しません (ただし、多数のラッパーが認識されます)。 この場合、アナライザーはメモリが割り当てられたことを認識せず、この警告を発行します。 擬陽性を抑制するには、関数本体の左中かっこ { の前の行で #pragma ディレクティブを使用します。

これらの種類の潜在的なリークをすべて回避するには、C++ の標準テンプレート ライブラリ (STL) で提供されているメカニズムを使用します。 これには、shared_ptrunique_ptrvector などがあります。 詳細については、「スマート ポインター」および「C++ 標準ライブラリ」を参照してください。

// cl.exe /analyze /EHsc /nologo /W4
#include <sal.h>
#include <memory>

using namespace std;

_Analysis_mode_(_Analysis_local_leak_checks_)

const int ARRAYSIZE = 10;
const int TEST_DATA [ARRAYSIZE] = {10,20,30,40,50,60,70,80,90,100};

void f( )
{

    unique_ptr<int[]> p(new int[ARRAYSIZE]);
    std::copy(begin(TEST_DATA), end(TEST_DATA), p.get());

    // code ...

    // No need for free/delete; unique_ptr
    // cleans up when out of scope.
}

int main( )
{
    f();
}

関連項目

C6211