CL.MLK.ASSIGN
代入演算子のメモリ リーク
これは演算子 = のメモリリークの可能性を通知するクラスレベル (CL) のチェッカーです。Klocwork は、コンストラクタで動的メモリ割り当てを行うクラスが演算子 = の対応するポインターを上書きし、前のメモリを解放せず、および/または適切なリファレンスカウンターを減分しない場合に、CL.MLK.ASSIGN をレポートします。これはメモリリークにつながる可能性があります。
脆弱性とリスク
メモリリークは、アプリケーションで余分なメモリを消費させます。これによって他のアプリケーションが使用できるメモリ量が減り、結果的に、オペレーティングシステムにページングを開始させ、システム速度を低下させます。重大な場合、アプリケーションがメモリ制限に達して、クラッシュする可能性があります。
脆弱コード例 1
コピー
class C {
public:
C() { ip = new int; }
~C() { delete ip; }
C& operator=(const C& rhs) {
if (this == &rhs) return *this;
ip = new int; // memory pointed by ip is leaked
*ip = *rhs.ip;
return *this;
}
private:
C(const C&);
int* ip;
};
この例では、ip がポイントするメモリは上書きされる前に解放されません。コンストラクタでこのポインターにメモリが割り当てられるため、この代入はメモリリークにつながる可能性があり、これは Klocwork によって CL.MLK.ASSIGN とレポートされます。
修正コード例 1
コピー
class C {
public:
C() { ip = new int; }
~C() { delete ip; }
C& operator=(const C& rhs) {
if (this == &rhs) return *this;
delete ip;
ip = new int;
*ip = *rhs.ip;
return *this;
}
private:
C(const C&);
int* ip;
};
修正例 1 では、ip がポイントする動的メモリは新しい値に割り当てられる前に行 7 で解放されます。
脆弱コード例 2
コピー
class counted {
public:
counted() { counter = 1; }
void addRef() { counter++; }
void decRef() { counter--; if (counter == 0) delete this; }
/* other methods */
private:
int counter;
/* other members */
};
class C {
public:
C() { cp = new counted; }
~C() { cp->decRef(); }
C& operator=(const C& rhs) {
if (this == &rhs) return *this;
cp = rhs.cp; // CL.MLK.ASSIGN reported
cp->addRef();
return *this;
}
private:
C(const C&);
counted* cp;
};
この例では、cp がポイントするメモリのリファレンスカウンターは上書きする前に減分されません。その結果メモリリークにつながる可能性があり、Klocwork によって CL.MLK.ASSIGN とレポートされます。
修正コード例 2
コピー
class counted {
public:
counted() { counter = 1; }
void addRef() { counter++; }
void decRef() { counter--; if (counter == 0) delete this; }
/* other methods */
private:
int counter;
/* other members */
};
class C {
public:
C() { cp = new counted(); }
~C() { cp->decRef(); }
C& operator=(const C& rhs) {
if (this == &rhs) return *this;
cp->decRef();
cp = rhs.cp;
cp->addRef();
return *this;
}
private:
C(const C&);
counted* cp;
};
これでリファレンスカウンターは減分され、欠陥のレポートはありません。
拡張機能
このチェッカーは、Klocwork knowledge base (ナレッジベース) を利用して拡張できます。詳細については、C/C++ 解析のチューニングを参照してください。