2

最近、コードでクラッシュが発生し、クラッシュの方法と理由がわからず、静的アナライザーを使用し始めました。その後、Intel Inspector XE 2013を使用し始めました。コードで同じ「無効なメモリアクセス」が発生し続けたため、コードを可能な限り最小の形式に縮小して再現し始めました。最終的に、クラスにデストラクタがある場合にのみ、コードに「無効なメモリアクセス」があるように見えるようになりました。興味深いのは、削除しようとしているアドレスの前にあるアドレスで「無効なメモリアクセス」が発生していることです。「無効なメモリアクセス」になってしまったコードは、実際にはコードをクラッシュさせていませんが、雪だるま式に影響があった場合は、この潜在的な問題を修正すると思いました。問題の私のコードは

class Group {
public:
    Group() {}
    ~Group() {} // When this line is not here, there will not be an "Invalid memory access"
};

int main() {
    Group** groups = new Group*[3];

    groups[0] = new Group();
    groups[1] = new Group();
    groups[2] = new Group();

    for(unsigned int i = 0; i < 3; ++i)
        delete [] groups[i];

    delete [] groups;

    return 0;
}

「無効なメモリアクセス」の問題は、最初に「delete [] group [i]」を試行したときにフラグが立てられます(したがって、iは0に等しくなります)。フラグが立てられているメモリアドレスは「0x003e30ec」ですが、group [0]は実際には「0x003e30f0」であり、0x4先です。私がこのテストを実行するときはいつでも、それは常に0x4の差にあります。

私の質問は、メモリの読み取りまたは書き込みが不適切なコードに実際に何か問題があるのか​​、それともこの人がIntel Inspector XE 2013(Visual Studio 2012 Update 1を使用している)の悪い結果なのかということです。

上記の例で私のメモリテーブルに興味がある人のために、それは次のとおりです

groups == 0x003e30b8
groups[0] == 0x003e30f0
groups[1] == 0x003e3120
groups[2] == 0x003e3150
4

2 に答える 2

5
for(unsigned int i = 0; i < 3; ++i)
        delete [] groups[i];

する必要があります

for(unsigned int i = 0; i < 3; ++i)
        delete  groups[i];

new/deletenew [] /delete []常に一致する必要があります。あなたの場合、単に使用std::vector<std::shared_ptr<Group> > groups;する方が良い方法です。

最終的に、コードに「無効なメモリアクセス」があるように見えるポイントに到達しましたが、クラスにデストラクタがある場合のみです。

wrong delete[]この場合、デストラクタに何かが隠されている場合を除き、デストラクタとは何の関係もありませんが、それは別のバグになります。

于 2012-12-07T06:10:27.957 に答える
1

あなたの問題は、 array-style をdelete []使用していて、通常のものだけを使用する必要があることだと思いますdelete。これは、 の各要素groupsが単一のGroupオブジェクトであり、配列ではないためです。

delete []ただし、groupsメモリには使用する必要があります。

于 2012-12-07T06:11:53.120 に答える