質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.47%

  • C++

    3586questions

    C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

  • Visual Studio

    1904questions

    Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

【C++】ヒープが破壊されます(>_<)

受付中

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 3,862

mash0120

score 2

C++初心者です。
ヒープ破壊のエラーに、かれこれ2週間ほど苦しめられております。
何かわかる方いましたら回答をお願いします...助けてください...(>_<)汗

【発生手順】
「CreateBuffer」というFunctionで、pA1~pA16のバッファを作成します。
そして、pA1~pA16が作られた状態で「DeleteBuffer」が呼ばれるとpA1~pA16をdeleteしていきます。
pA15~pA16辺りをdeleteするときに以下のエラーが発生します。(たいていはpA16でエラーが発生する)

Windows によって HogeHoge.exe でブレークポイントが発生しました。
ヒープが壊れていることが原因として考えられます。HogeHoge.exe または読み込まれた DLL にバグがあります。
あるいは、HogeHoge.exe がフォーカスを持っているときに、ユーザーが F12 キーを押したことが原因として考えられます。
可能であれば、出力ウィンドウに詳細な診断情報が表示されます。

「CreateBuffer」でpA1~pA16をnewした直後に「DeleteBuffer」を呼んでみても同様のエラーが発生するので、構造体の作り方が悪かったりするのかなと考えているところです。

説明が不足している点は聞いていただければと思います。
皆さんのお知恵をお貸しください。よろしくお願いします。

また、ソースですがお見せすることができない場所もありますので、これがソースのすべてではありません。限られた情報しか提示できませんがご協力お願いします(ToT)

以下、問題のソースです。

typedef struct AData{
    BYTE            *pA1;            //A1ポインタ
    BYTE            *pA2;            //A2ポインタ
    BYTE            *pA3;            //A3ポインタ
    BYTE            *pA4;            //A4ポインタ
    BYTE            *pA5;            //A5ポインタ
    BYTE            *pA6;            //A6ポインタ
    BYTE            *pA7;            //A7ポインタ
    BYTE            *pA8;            //A8ポインタ
    BYTE            *pA9;            //A9ポインタ
    BYTE            *pA10;            //A10ポインタ
    BYTE            *pA11;            //A11ポインタ
    BYTE            *pA12;            //A12ポインタ
    BYTE            *pA13;            //A13ポインタ
    BYTE            *pA14;            //A14ポインタ
    BYTE            *pA15;            //A15ポインタ
    BYTE            *pA16;            //A16ポインタ
}
void HogeHoge::CreateBuffer( Int32 bufferSize )
{
    this->DeleteBuffer();
    this->data->pA1 = new BYTE[ bufferSize ];
    this->data->pA2 = new BYTE[ bufferSize ];
    this->data->pA3 = new BYTE[ bufferSize ];
    this->data->pA4 = new BYTE[ bufferSize ];
    this->data->pA5 = new BYTE[ bufferSize ];
    this->data->pA6 = new BYTE[ bufferSize ];
    this->data->pA7 = new BYTE[ bufferSize ];
    this->data->pA8 = new BYTE[ bufferSize ];
    this->data->pA9 = new BYTE[ bufferSize ];
    this->data->pA10 = new BYTE[ bufferSize ];
    this->data->pA11 = new BYTE[ bufferSize ];
    this->data->pA12 = new BYTE[ bufferSize ];
    this->data->pA13 = new BYTE[ bufferSize ];
    this->data->pA14 = new BYTE[ bufferSize ];
    this->data->pA15 = new BYTE[ bufferSize ];
    this->data->pA16 = new BYTE[ bufferSize ];
    this->DeleteBuffer(); //テスト用に追加
}
void HogeHoge::DeleteBuffer()
{
    if( this->data->pA1 != NULL )
    {
        delete[] this->data->pA1;
        this->data->pA1 = NULL;
    }
    if( this->data->pA2 != NULL )
    {
        delete[] this->data->pA2;
        this->data->pA2 = NULL;
    }
    if( this->data->pA3 != NULL )
    {
        delete[] this->data->pA3;
        this->data->pA3 = NULL;
    }
    if( this->data->pA4 != NULL )
    {
        delete[] this->data->pA4;
        this->data->pA4 = NULL;
    }
    if( this->data->pA5 != NULL )
    {
        delete[] this->data->pA5;
        this->data->pA5 = NULL;
    }
    if( this->data->pA6 != NULL )
    {
        delete[] this->data->pA6;
        this->data->pA6 = NULL;
    }
    if( this->data->pA7 != NULL )
    {
        delete[] this->data->pA7;
        this->data->pA7 = NULL;
    }
    if( this->data->pA8 != NULL )
    {
        delete[] this->data->pA8;
        this->data->pA8 = NULL;
    }
    if( this->data->pA9 != NULL )
    {
        delete[] this->data->pA9;
        this->data->pA9 = NULL;
    }
    if( this->data->pA10 != NULL )
    {
        delete[] this->data->pA10;
        this->data->pA10 = NULL;
    }
    if( this->data->pA11 != NULL )
    {
        delete[] this->data->pA11;
        this->data->pA11 = NULL;
    }
    if( this->data->pA12 != NULL )
    {
        delete [] this->data->pA12;
        this->data->pA12 = NULL;
    }
    if( this->data->pA13 != NULL )
    {
        delete [] this->data->pA13;
        this->data->pA13 = NULL;
    }
    if( this->data->pA14 != NULL )
    {
        delete [] this->data->pA14;
        this->data->pA14 = NULL;
    }
    if( this->data->pA15 != NULL )
    {
        delete [] this->data->pA15;
        this->data->pA15 = NULL;
    }
    if( this->data->pA16 != NULL )
    {
        delete [] this->data->pA16;
        this->data->pA16 = NULL;
    }
}


↓以下追加のソースです。

HogeHoge.h

public ref class HogeHoge // データ取得バッファ(アンマネージ)のラッパ
{
private:
    FUGA_AREA* data;    // データ取得バッファ

public:
    int BufferSize;    // バッファのサイズ
    HogeHoge(void);    // コンストラクタ
    ~HogeHoge(void);    // デストラクタ
    !HogeHoge(void);    // ファイナライザ
    FUGA_AREA* GetReference();    // データ取得バッファのポインタを取得する
    void CreateBuffer( Int32 bufferSize ); // バッファを作成
    void DeleteBuffer();        // バッファを削除

public:
    ///
    /// プロパティ
    ///

    property String^ IdName    // ID名(S1~S100,R1~R100,M1~M100)(Read Only)
    {
        String^ get()
        { 
            std::string s( this->data->aIdName );
            return Utility::ToUnicode( s );
        }
    };

    property UInt32 AMaxSize    // データ最大数(AデータのMAX値)(Read Only)
    {
        UInt32 get(){ return this->data->nMax; }
    };

    property UInt32 Count    // データ個数(property)
    {
        UInt32 get(){ return this->data->nCnt; }
        void set( UInt32 value ){ this->data->nCnt = value; }
    };

    property Int32 CountReference    // データ個数のポインタ(Read Only)
    {
        Int32 get(){ return (int)( &(this->data->nCnt) ); } 
    };

    property UInt32 StartPosition    // データ開始位置(Read Only)
    {
        UInt32 get(){ return this->data->nStp; }
    };

    property UInt32 EndPosition        // データ終了位置(Read Only)
    {
        UInt32 get(){ return this->data->nEnp; }
    };

    property String^ DataType    // データ型(Read Only)
    {
        String^ get()
        {
            std::string s( this->data->aDataType );
            return Utility::ToUnicode( s );
        }
    };

    property Int32 DataLength    // データ長(Read Only)
    {
        Int32 get(){ return this->data->nDataLength; }
    };

    property Int32 Status    // 状態(Read Only)
    {
        Int32 get(){ return this->data->nStatus; }
    };

    property Int32 A1Reference        //A1データのポインタ(Read Only)
    {
        Int32 get()
        { return (int)( &( this->data->pA1[0] ) ); }
    };

    property Int32 A2Reference        //A2データのポインタ(Read Only)
    {
        Int32 get()
        { return (int)( &( this->data->pA2[0] ) ); }
    };

    property Int32 A3Reference        //A3データのポインタ(Read Only)
    {
        Int32 get()
        { return (int)( &( this->data->pA3[0] ) ); }
    };

    property Int32 A4Reference        //A4データのポインタ(Read Only)
    {
        Int32 get()
        { return (int)( &( this->data->pA4[0] ) ); }
    };

    property Int32 A5Reference        //A5データのポインタ(Read Only)
    {
        Int32 get()
        { return (int)( &( this->data->pA5[0] ) ); }
    };

    property Int32 A6Reference        //A6データのポインタ(Read Only)
    {
        Int32 get()
        { return (int)( &( this->data->pA6[0] ) ); }
    };

    property Int32 A7Reference        //A7データのポインタ(Read Only)
    {
        Int32 get()
        { return (int)( &( this->data->pA7[0] ) ); }
    };

    property Int32 A8Reference        //A8データのポインタ(Read Only)
    {
        Int32 get()
        { return (int)( &( this->data->pA8[0] ) ); }
    };

    property Int32 A9Reference        //A9データのポインタ(Read Only)
    {
        Int32 get()
        { return (int)( &( this->data->pA9[0] ) ); }
    };

    property Int32 A10Reference        //A10データのポインタ(Read Only)
    {
        Int32 get()
        { return (int)( &( this->data->pA10[0] ) ); }
    };

    property Int32 A11Reference        //A11データのポインタ(Read Only)
    {
        Int32 get()
        { return (int)( &( this->data->pA11[0] ) ); }
    };

    property Int32 A12Reference        //A12データのポインタ(Read Only)
    {
        Int32 get()
        { return (int)( &( this->data->pA12[0] ) ); }
    };

    property Int32 A13Reference        //A13データのポインタ(Read Only)
    {
        Int32 get()
        { return (int)( &( this->data->pA13[0] ) ); }
    };

    property Int32 A14Reference        //A14データのポインタ(Read Only)
    {
        Int32 get()
        { return (int)( &( this->data->pA14[0] ) ); }
    };

    property Int32 A15Reference        //A15データのポインタ(Read Only)
    {
        Int32 get()
        { return (int)( &( this->data->pA15[0] ) ); }
    };

    property Int32 A16Reference        //A16データのポインタ(Read Only)
    {
        Int32 get()
        { return (int)( &( this->data->pA16[0] ) ); }
    };
}


HogeHoge.cpp

///
/// 機能 : コンストラクタ
///
HogeHoge::HogeHoge(void)
{
    this->data = new FUGA_AREA;
    memset( this->data, 0, sizeof( FUGA_AREA ) );
    this->BufferSize = 0;
    strcpy_s( this->data->aIdName, sizeof(this->data->aIdName), "R1" );
}

///
/// 機能 : デストラクタ
///
HogeHoge::~HogeHoge(void)
{
    this->!HogeHoge();
}

///
/// 機能 : ファイナライザ
///
HogeHoge::!HogeHoge()
{
    this->DeleteBuffer();

    if( this->data != NULL )
    {
        delete this->data;
        this->data = NULL;
    }
}
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

+1

こんにちは。

HogeHogeクラスの定義がないとよく分かりませんので、できればそれも提示下さい。

ご提示のソースで分かる範囲で答えてみます。
まず、pA1~pA16を初期化されてますでしょうか? 初期化しないとpA1~pA16の値は不定になります。
次に、DeleteBuffer()のpA12 以降の処理がそれ以前と順序が異なってます。この辺は単純ミスでは?

最後に、CreateBuffer()の先頭でDeleteBuffer()を呼んでいるのはなぜでしょうか?
HogeHogeクラス定義でpA1~pA16を初期化されているのであれば、念のための処理ということでしょうか?


【追記】
aIdNameがADataに含まれていないようです。
これの定義を間違っているということはないでしょうか?
何かミスしているとstrcpy_s()でヒープ破壊の可能性は若干あります。

さて、ビルドしてやってみようとしたのですが、手間が掛かりそうなので諦めました。
C++/CLIを知らないので#includeするべきヘッダが分かりません。
ADataのtypedefも尻切れトンボになってます。
ビルドできて、かつ、エラーが再現する最小限のソース・コードにして頂けると、何かお手伝いできるかも知れません。(申し訳ないけど保証はできないですが...)

ところで、C++/CLIはマイクロフソト・オリジナルなC++ライク言語で、C++ではありません。
もし、特に必要があるというわけでないのならば、通常のC++を使った方が知っている人が多いのでフォローも受けやすいし、WEB情報も多いですよ。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/04/16 19:44

    被っちゃいましたね。

    キャンセル

  • 2016/04/16 20:56 編集

    構造体の初期化ができていないとそのような事が起きるのですね...また追加でソースを載せました。恐れ入りますが、どの辺に問題がありそうかご教授ください。お願いします(ToT)

    キャンセル

  • 2016/04/16 21:25

    C++/CLIだったのですね。CLIは殆ど知らないのでお役に立てないかもしれませんが、トライしてみます。ちょっとおまちを。

    キャンセル

  • 2016/04/16 21:27

    catsforepawさん。

    しかも、今度は分まで。偶然って意外に身近に起こるものなんですね。

    キャンセル

  • 2016/04/16 22:43

    C++/CLIはC++にマネージ拡張を施したものですが、C++としての仕様はほぼC++そのものです。cstdio(stdio.h)をインクルードしてprintfすることもできますし、STLも使えます。

    キャンセル

  • 2016/04/16 22:54 編集

    マクロソフトのオリジナルな拡張がなされた言語ですね。
    C++ライクというよりはC++上位互換な言語と言った方が妥当でした。

    ただ、tomomi_321さんはC++では使えない機能をバリバリつかってます。分かって使っているのであれば良いのですが、C++初心者を名乗られてますし、C++と思っているとやばいかと思って少し強い表現を使いました。

    キャンセル

  • 2016/04/16 23:29

    意図して書いたのでしたか。早とちりしてすみません。

    キャンセル

+1

CreateBufferメソッドで、最初にDeleteBufferメソッドを呼び出していますが、この時点でAData構造体の各メンバ変数はNULLに初期化されていますでしょうか。ちゃんと初期化されていないと不正なポインタに対してdeleteやdelete[]を実行することになり、ヒープを壊す可能性があります。

それと、deleteおよびdelete[]はnullの時は何もしないという仕様なので、if( this->data->pA1 != NULL )のような判定は不要です。
また、delete[]とNULLの代入の順番を間違えている箇所がいくつもあります。メモリリークを引き起こします。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/04/16 21:01

    「deleteおよびdelete[]はnullの時は何もしないという仕様」なのですね。無駄な処理でしたか。。また追加でソースを載せました。他にもどこか問題がありそうな場所があればご教授ください。お願いします。

    キャンセル

  • 2016/04/16 22:31

    マネージコードでしたか。ポインタはInt32ではなく`IntPtr`でキャストしてください。

    とりあえず、ヒープ破壊につながるような問題は特に見当たりません。HogeHogeクラスを使う側に問題があるような気がします。どのように使っているのか判りませんが、バッファーサイズを超えてデータを書き込んだりしていませんか?

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.47%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • C++

    3586questions

    C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

  • Visual Studio

    1904questions

    Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。