0

次の C++ コードを使用すると、実行時に未処理の例外エラーが発生しました。Visual Studio を使用してデバッグでエラーを追跡できます。なぜこの例外が発生するのでしょうか、説明していただけますか?

まず、メンバー変数「_name」でクラスを定義します

void insert_Fenster(int pos,wstring name);
wstring get_Fenster_name(int pos);

class Fenster
{
public:
    Fenster(wstring name)
        :_name(name)
    {}

    void reload()
    {
        _name;
        insert_Fenster(1,L"temp");
        wstring tmp = get_Fenster_name(1);
        _name = tmp; //ERROR!!!
    }

    wstring get_name()
    {
        return _name;
    }

private:
    wstring _name;
};

次に、クラスのマップを保持するクラスを定義します

class FensterManager
{
public:
    bool has(int pos)
    {
        if (_mapFenster.find(pos)!=_mapFenster.end())
            return true;
        else
            return false;
    }

    void insert(int pos,wstring name)
    {
        if (has(pos))
        {
            _mapFenster.erase(pos);
        }
        _mapFenster.insert(make_pair(pos,Fenster(name)));
    }

    Fenster& get_Fenster(int pos)
    {
        return _mapFenster.at(pos);
    }

private:
    static map<int,Fenster> _mapFenster;
};

そしていくつかのユーティリティ関数

void insert_Fenster(int pos,wstring name)
{
    FensterManager fm;
    fm.insert(pos,name);
}

void reload_Fenster(int pos)
{
    FensterManager fm;
    if (fm.has(pos))
        fm.get_Fenster(pos).reload();
}

wstring get_Fenster_name(int pos)
{
    wstring name;

    FensterManager fm;
    if (fm.has(pos))
        name = fm.get_Fenster(pos).get_name();

    return name;
}

//Init of static member before main function
map<int,Fenster> FensterManager::_mapFenster;

それが主な機能です

void main()
{
    insert_Fenster(1,L"xyz");
    reload_Fenster(1);
}

クラス「Fenster」の「reload」関数で例外が発生します。

エラー メッセージ: Regular_Expression.exe の 0x005cca34 (msvcr100d.dll) で未処理の例外: 0xC0000005: アクセス違反の書き込み場所 0xfeeefeee.

4

3 に答える 3

3

を呼び出すとreload_Fenster(1);、 が呼び出されますFenster::reload。その関数では、 を呼び出しますinsert_Fenster(1,L"temp");FensterManager::insert最初にマップから位置 1 を消去します。に戻るとFenster::reload、インスタンスは削除されています。にアクセスしようとする_nameと、削除されたメモリにアクセスしようとします。

編集: 明確にするために。この関数呼び出し:

fm.get_Fenster(pos).reload();

最初に呼び出しfm.get_Fenster(pos)、次にreload()結果を呼び出します。関数fm.get_Fenster(pos)が変更されたreload()場合、実行は新しい Fenster を移動しませんが、古い Fenster は実行を続けます。古いフェンスターを削除しても。

インスタンス内で関数を実行している場合は、インスタンスを削除しないように注意してください。メンバーは削除されたメモリに保存されているため、メンバーにアクセスしようとするとすぐにアプリケーションがクラッシュします。

于 2013-10-11T09:54:35.057 に答える
0

未処理の例外に関する詳細情報を提供してください。

上記のコードには明らかな間違いが 1 つあります。insert_Fenster が FensterManager インスタンスに挿入され、reload_Fenster が FensterManager の別のインスタンスから再ロードしようとしていますが、これは間違っています。

void main()
{
    FensterManager fm;
    insert_Fenster(fm, 1,L"xyz");
    reload_Fenster(fm, 1);
}

insert および reload メソッドは、次のように更新する必要があります。

void insert_Fenster(FensterManager &fm, int pos,wstring name)
{
    fm.insert(pos,name);
}

void reload_Fenster(FensterManager &fm, int pos)
{
    if (fm.has(pos))
        fm.get_Fenster(pos).reload();
}
于 2013-10-11T09:43:39.357 に答える
0

内部の何かのようにvoid insert_Fenster(int pos,wstring name);見えます - コール スタックをさらに調べると、コードのどの部分がランタイム dll を呼び出しているかがわかります。それがエラーになります。

于 2013-10-11T09:42:01.460 に答える