0

私はこの非常に単純なダミープログラムを持っています

levenshteindb.h :

#ifndef LEVENSHTEINDB_H
#define LEVENSHTEINDB_H

#include <QVector>
#include "levenshteindbnode.h"

class LevenshteinDB
{
    unsigned size;
    QVector<LevenshteinDBNode> nodes;
    void realloc_rows(unsigned node);

public:
    LevenshteinDB();
    ~LevenshteinDB();
    void add_word();
};

#endif // LEVENSHTEINDB_H

levenshteindb.cpp :

#include "levenshteindb.h"
#include <cstring>
#include <cstdio>    

LevenshteinDB::LevenshteinDB()
{
    size=15;
    nodes.append(LevenshteinDBNode(size));
}

LevenshteinDB::~LevenshteinDB()
{
}


void LevenshteinDB::add_word()
{
    nodes.append(LevenshteinDBNode(size));
}


void LevenshteinDB::realloc_rows(unsigned newsize)
{
    for(unsigned i=0;i<nodes.size();i++)
        nodes[i].realloc(newsize);
}

levenshteindbnode.h :

#ifndef LEVENSHTEINDBNODE_H
#define LEVENSHTEINDBNODE_H

struct LevenshteinDBNode
{
    LevenshteinDBNode();
    LevenshteinDBNode(unsigned size);
    ~LevenshteinDBNode();
    unsigned *row;
    void realloc(unsigned newsize);
};

#endif // LEVENSHTEINDBNODE_H

levenshteindbnode.cpp :

#include "levenshteindbnode.h"

LevenshteinDBNode::LevenshteinDBNode(){};

LevenshteinDBNode::LevenshteinDBNode(unsigned size)
{
    row = new unsigned[size];
}

LevenshteinDBNode::~LevenshteinDBNode()
{
    delete[] row;
}

void LevenshteinDBNode::realloc(unsigned newsize)
{
    delete[] row;
    row=new unsigned[newsize];
}

main.cpp :

#include "levenshteindb.h"

int main()
{
    LevenshteinDB *trie = new LevenshteinDB();
    trie->add_word();
    trie->add_word();
    trie->add_word();
    delete trie;
}

それがクラッシュし、(プログラム自体によって割り当てられたメモリと比較して)巨大なメモリリークが発生しているように見えますが、何が問題なのか本当に理解できません..qt 5.2を使用しています

4

1 に答える 1

3

3 のルールについて読む必要があります。

何が起こっているかというと、

nodes.append(LevenshteinDBNode(size));

一時的な LevenshteinDBNodeobjectm を作成してからコピーすると、同じメモリへの 2 つのポインターを持つ 2 つのオブジェクトが作成されます。次に、一時オブジェクトが破棄され、デストラクタが呼び出され、割り当てたメモリが削除されます。これで、削除されたメモリへのポインターを含むオブジェクトのコピーが作成されました。

割り当てられたメモリのいわゆるディープ コピーを行うコピー コンストラクタを実装する必要があります。


LevenshteinDBNodeまた、デフォルトのコンストラクターでポインターを初期化しないという点で、コードにははるかに微妙なエラーがあります。これは、デフォルトで構築されたインスタンスがある場合、ポインターは不確定な値を持ち、実際にはランダムな場所を指すことを意味します。deleteこのランダム ポインターを使用しようとしたときに、既定で構築されたインスタンスが破棄されると、未定義の動作が発生します。nullptrデフォルトのコンストラクターでポインターを初期化する必要があります。

于 2014-01-08T09:53:03.087 に答える