• 締切済み

VisualC++6.0でdeleteがおかしい

今頃ですが、VisualC++6.0を使っています。とりあえずはこれで十分なので。で、WindowXPです。 1つのMFCAppWizardメインプロジェクトに対して、3つのライブラリ専用のサブプロジェクトを統合してプログラムを作っていますが、下記の簡単なdeleteもなぜか、出来なくなりました。 long* p; p = new long; delete p; 実行するとdelete pのところで、 NTDLL! 7c9668ad() PRONAME! free + 45 bytes PRONAME! operator delete(void *) + 9 bytes PRONAMEDlg::OnBtnCapturepicture() line 267 + 15 bytes のようなエラーが出てきます(デバッグモード)。 ちょっと気になったのが、最近、VirusBusterをインストールしましたので、実行後に、 'C:\Program Files\Trend Micro\Virus Buster 2007\TMAS_OE\TMAS_OEHook.dll' をロードしました、合致するシンボル情報は見つかりませんでした。 などというコメントが出てくるようになりました。 しかし、ちなみに全く新しいMFCAppWizardテストプロジェクトを作って、他のプロジェクトとリンク等、いっさいせずに簡単なもので動かすと、上記のコード、全く問題なく動きます。 この delete のエラーって、何が原因なのでしょうか。 考えられることがおわかりであれば、教えてください。

みんなの回答

回答No.5

メインプロジェクトとサブプロジェクトの間で必要としているdllが違っていたりしませんか? 例えばどちらかはDebugビルドなのにどちらかはReleaseビルドだとか、 片方はシングルスレッド用なのに片方はマルチスレッド用だとか……

chachakabu
質問者

お礼

わたしもこの辺を疑っています。 デバッグとリリースモードを混在していることはありませんが、リンクしているライブラリがシングルスレッドとマルチスレッド用が混在していたり、、、というのは、もう一度調べてみないといけないかもしれません。 この辺がほんと、めんどくさいというかわからないところです。結構いろいろとライブラリを使用しているので。 混合してはいけないこととして、 ○デバッグモードとリリースモード ○マルチスレッドとシングルスレッドのライブラリ ○ダイナミック用ライブラリとスタティック用ライブラリ ほんとめんどくさいですよねえ。 こんなの自動選択とかしてよって。 わたしもとりあえず思いつくのはこれですが、ほかにはなかったかな。 やはり、リンクしているライブラリの相性では、というのが、今のわたしの最大の疑問点です。 ありがとうございました。

  • guccii
  • ベストアンサー率31% (14/44)
回答No.4

なるほどぉ。困りましたねぇ。 同じようにプロジェクトを作成してみて思ったのですが、デバッグ版の場合、(確保したメモリのリストを管理しているので)参照しているヒープが違ったり、アドレスが多少ずれていたりした場合には、ASSERTする筈なんですよ。 で、今回はfree()の中でいきなり落ちてる... しかもこんな単純なコードで...。 断言することは尚早ですが、ライブラリのどこかでヒープを破壊している可能性が高いと思われます。確保したメモリ領域を超えてコピーしたり、ポインタ操作を誤って考えている以上の領域を使用したりしていないか見直した方が早いかもしれません。 確保しているヒープメモリに尖兵をつけて、破壊されていないかチェックするメモリ検査ロジックを追加するか、PURIFYみたいなメモリチェックをしてくれるソフトウエアを使って、メモリ不正がないか1度確認されたほうがよいのではないかと思われます。 くれぐれも断言はできませんが...

chachakabu
質問者

お礼

お返事ありがとうございました。 んーーん、やっぱり、これはちょっとかなり気合入れていろいろ調べていかないと、ちょっと一筋縄ではいきそうもありませんね。 VisualC++を使っていていつも思うのですが、複数のプロジェクトをリンクして使用する場合、それぞれのプロジェクトをコンパイルする際にどのライブラリをリンクしたかで、よくトラブルことがあります。今回の場合、サブプロジェクトにMFC系のライブラリ系をリンクして(共有MFCを使用するを選択するという意味)、メインでもMFC系のライブラリをリンクすると2重リンクでリンクエラーで落ちたり、スタティック系のライブラリかダイナミック系のライブラリかで、いちいち全部、チェックしてどのライブラリをリンクするかしないか、判断しないといけないので、やたらとめんどくさいです。スタンダード系のライブラリもメインとサブと両方デフォルトのままコンパイルすると、双方に入ってしまって、2重リンクになってしまったり。この辺が問題なのかなとも思っています。以前、マックのSymantecC++をしていましたが、こちらはほんとになんとも非常に使いやすかったですよ。それに比べて、VisualC++はなんともほんとに使いにくいです。 VisualC++も個々のプロジェクトをコンパイルするときはMFCやスタンダードライブラリを一緒にリンクすることをやめて、最後、全体をリンクするときに全部まとめてリンクすればいいのにね。ほんと、めちゃくちゃやっかいです。 んーーん、根性入れて、徹底的に調べるかな、、、どうしよう。。。

  • guccii
  • ベストアンサー率31% (14/44)
回答No.3

>long* p; >p = new long; >delete p; は、この通りのコードでしょうか?DLLで確保したメモリをEXEの中でdeleteしていたりしていないでしょうか? もしそうであれば、そのDLLの中にメモリを解放する関数を作って、EXEはそれを呼び出すようにしてください。 そうでない(上記の通りのコードで問題がでている)のなら、ちょっと厄介ですね。やってみてみないとなんともいえません。

chachakabu
質問者

お礼

コードは、まったくこのとおり、連続してこの順番なのですよ。 テスト用に全くこのとおりに挿入してみました。もともとは、クラスを作成して、それを new して使用したあと、delete しようとしたら出来なくて、調べているうちに、たった3行の簡単なコード long* p; p = new long; delete p; も出来ないことが判明しました。 うーーん、、、困った。 ちなみにこのテストコードは3つのサブプロジェクトではなく、メインプロジェクトの方に入れています。

  • guccii
  • ベストアンサー率31% (14/44)
回答No.2

不正なアドレスでdeleteしているものと思われます。 2重フリーしていない、該当ポインタにアドレス操作をしていないで、かつ、他の部分でメモリを壊していないとすると、考えられるパターンとしては、 1.EXEとDLLがそれぞれ別のランタイムとなっている。つまり、別のヒープから取得したメモリを別のヒープからdeleteしようとしている。EXEとDLLがそれぞれCのランタイムをスタティックにリンクしていませんか? 2.リリース版で取得したメモリをデバッグ版で解放しようとしている。MFCでデバッグ版の場合には、特別なnewが使用されて、デバッグ情報+確保したメモリ分のメモリが取得されます。newから実際に帰ってくるアドレスは、確保したメモリの先頭アドレスですが、deleteする際には、その前にデバッグ情報が存在していることを想定して動作します。このため、リリース版でアロケートしたメモリをデバッグ版でフリーしようとすると不正アドレスのフリーとなってしまいます。 というところではないでしょうか? "VirusBuster"と一緒に使用したことはないのではっきりとはわかりませんが、単にメモリ不正アクセス検査か何かのフックが呼ばれるようになっているのだと思います。今回の問題との直接的な関連については懐疑的です。

chachakabu
質問者

お礼

今、わたしが疑っているのは、リンクの仕方です。 メインは、MFCAppWizard(exe)ですが、他の3つは、Win32 Static Libraryで作っていて、MFCサポートありにしています。 それで、メインからコンパイルする際に、”設定”のところで、3つのサブプロジェクトはMFCを使用しないにしていて、メインAppは共有DLLでMFCを使用するにしています。すべてデバッグモードです。 また、オプションには /nodefaultlib:"nafxcwd.lib" /nodefaultlib:"msvcrtd.lib" /nodefaultlib:"libcd.lib" を設定しています。 これらの設定しないとリンクエラーになります。 この辺があやしいのでしょうか。

  • Interest
  • ベストアンサー率31% (207/659)
回答No.1

new したときにメモリが確保できていないとか? 確保できていないのに delete すると、プログラムが落ちますよね。 Visual C++ではnew演算子の動作が失敗したときにデフォルトでNULLを返しますが、現在の標準C++ではデフォルトで例外を生成するんだそうです。 ためしに、 long* p; p = new long; if(!p){ cout << "メモリ割り当てエラー\n"; return 1; } delete p; としてメモリが確保できているかどうか確認してみてはいかがでしょうか。

chachakabu
質問者

お礼

残念ながら p には値が設定されていたし、 *p = 10; とかを入れてみても、ちゃんと値が入っていました。

関連するQ&A

  • VISUALC++6.0スタンダード版について

    プログラミングのレポートがでたのですがVISUALCは使ったことがなくてさっぱりわかりません。BORLANDCをつかって勉強したことがかなり昔にあるんですがその時はファイル新規作成してプログラムをうって実行させるとエラーまたは結果がでてました。でもVISUALCだとプロジェクトやらなんやらさっぱり解かりません。適当にしてるとファイルがないとかエラーがでるわけないのにエラーが出たりとか実行結果が出なかったりとわけわかりません。プログラミング自体ほとんど初心者です。3乗根をN-R法で求めるプログラムを直ちにつくらないといけないのですがVISUALCの使い方がさっぱりわからず焦ってます。とりあえず #include<stdio.h> int main() { printf("rarara\n"); } というプログラムさせ動かし方がわかりません。 どなたかアドバイスおねがいします。説明書読んでも分厚すぎるし時間がないしで メチャ困ってます。初心者でホントすいませんがおねがいします

  • VisualC++6.0

    VisualC++6.0のconsole applicationを使いC言語の勉強をしはじめているところなのですがプログラムを実行してもすぐ画面が閉じてしまい、実行結果を見れないのですが見るようにできますか?

  • VisualC++でエラーが大量に

    学友がVisualC++で困っています。 私では力になりません 代わりに救済をお願いします。 彼曰く VisualC++2005をインストール。 C++設定で新規プロジェクトをウィザードを使って、MFCアプリケーションスタイルで作成してすぐにビルドを行うとエラーが109件。 エラーの中には構成文エラーや「識別子が定義されていない」などのエラーが含まれます。 原因と対策お願いします

  • VisualC++.netの実行ファイル(.exe)

    VisualC++.netを今日インストールしたばかりです。どうにかこうにかプログラムを実行してみたのですが、デバッグが開始されず、実行ファイル(.exe)も作成されません。VisualC++.6.0で作ったプログラムで、エラーも出なかったものなので、プログラムに問題はないはずなのですが・・・一体何が問題なのでしょうか。誰か教えて下さい。本当に困っています・・・

  • VisualC++の新規作成について。

    ちょっと古いですが、Windows98で「Visual C++ 6.0」を使用しています。C言語の解説本を見てを勉強しようとしている初心者です。 新規作成するときに[ファイル][新規作成][プロジェクト][Win32 Console Application]と選択して進み、プロジェクト名を入力して、[OK]を押すと [作成するコンソールアプリケーションの種類を選択してください] と表示され、 [空のプロジェクト] [単純アプリケーション] ["Hello,World!"アプリケーション] [MFCをサポートするアプリケーション] の四つの中から選ぶようになります。 作成する、プログラムは初心者向けの解説本に載っているようなまだ短めのプログラムなのですが、どれを選択すればよろしいのでしょうか? ためしに # include <stdio.h> int main(void) { printf("%d", 15 + 37); return(0); } とのプログラムを入力してコンパイルしてみましたが、 コンパイル中... prg.cpp c:\prg\prg.cpp(4) : fatal error C1083: プリコンパイル済ヘッダー ファイルがオープンできません。'Debug/prg.pch': No such file or directory cl.exe の実行エラー prg.obj - エラー 1、警告 0 と表示されてしまいます。 このまま、ビルドしようとしても 「ソース ファイル"C:\prg\prg.c"と"C:\prg\prg.cpp"はともに出力ファイル"C:\prg\Debug\prg.obj"を作成するために設定されています。プロジェクトをビルドできません」 と表示されるのです。 プログラムのプロジェクト名は「prg」で、ファイル名は「prg.c」です。 どなたか解決策をよろしくお願いいたいます。

  • windows7の「アクションセンター」

    質問させていただきます。 windows7を使っているのですが、 先ほどPCを起動させたところ、 「アクションセンター」から下記の内容のお知らせが出ました。 「このプログラムを実行しますか? 信頼している発行元から提供されたプログラムのみを実行 してください。 発行元:Trend Micro,Inc. プログラム:C:\Program Files\Trend Micro\VirusBuster\SfFnWSC.exe →はい、発行元を信頼し、このプログラムを実行します →いいえ、このプログラムを実行する前に発行元を確認します」 ウイルスバスターを使っているのですが、 このようなお知らせは初めて出ました。 メーカーのHPや、インターネットでも検索をしてみたのですが、 該当するものが見当たらず、 「プログラムを実行」にしてよいものか、困っております…。 初心者の質問で恐縮ですが、 ご回答いただけると幸いです。よろしくお願いいたします。

  • deleteで開放するとエラーになる原因がわからない

    deleteでメモリ開放するとエラーになる原因がわからないです。 下記のようなプログラムを作ったのですが、deleteのところでエラーがでます。 エラー内容は 「Windows によって ****.exe でブレークポイントが発生しました。 ヒープが壊れていることが原因として考えられます。****.exe または読み込まれた DLL にバグがあります。 あるいは、****.exe がフォーカスを持っているときに、ユーザーが F12 キーを押したことが原因として考えられます。 可能であれば、出力ウィンドウに詳細な診断情報が表示されます。」 とでます。 ソースは wchar_t *aaa = L"ほげほげ"; wchar_t bbb[200]; wcscpy(bbb, aaa); delete aaa; wprintf(L"%s\n", bbb); getchar(); です。 どこに原因があるのでしょうか? [環境] WindowsXP+VisualC++2008 UNICODE使用

  • newで生成したものをdelete[]で破棄するのは間違い?

    int* p = new int(0); と確保したものを、普通は delete p; と書いて破棄しますが、代わりに delete[] p; と書いて破棄しても問題はないのでしょうか? 非常に悪いコードなのですが..... <1>: int* p = new int(0); <2>: int* p = new int[x]; //xはどこかで値を設定済み このうちの、1か2かのどちらかでpに対して領域を割り付けた場合に、どちらもdelete[]で破棄しても問題ないか? という意味の質問です。 コンパイルして実行しても特にエラーを吐くことはありませんでしたが非常に心配です。

  • VisualC++2005 「C2039 SetWindowTextAがCButton のメンバでは無い」と出てしまう。

    VisualC++2005において、プロジェクト(ソリューション)を以下のように構成した場合に表記のエラーが出ます。 解決方法ご存知でしたら教えて下さい。 (MFC初心者です) 【構成】 ・新規のソリューションにMFCのMDI形式のプロジェクトを作成 ・さらにMFC拡張DLLのプロジェクトを作成する (1つのソリューションに2つのプロジェクトを同居させる) ・MDIのプロジェクトは特に何もしない ・MFC拡張DLL側でダイアログを1ヶ作成する ・作成したダイアログのクラスを作成 ・OnInitDialog()を作成 ・作成したダイアログにあるボタンにメンバ変数(例:m_Button)を割り当てる ・OnInitDialog()内でm_Button.SetWindowText("HOGE");と記述 ・コンパイルするとエラーが出る 【エラー】 error C2039: 'SetWindowTextA' : 'CButton' のメンバではありません。 1> c:\program files\microsoft visual studio 8\vc\atlmfc\include\afxwin.h(2990) : 'CButton' の宣言を確認してください。 特に変わったことをしているわけではありません。 さらに「m_Button.」と入力した時点で入力補助機能が働くので m_Buttonはちゃんと認識されていると思います。 'CButton' 固有のメンバ関数の使用には問題ありませんが、 継承されているメンバ関数はことごとくNGです。

  • delete演算子によるメモリ解放について

    MFC MDIプログラミングで、 Genericクラスで点、線、面クラスを作って、 オブジェクトを組み合わせて 3次元図形を作っています。 図形を削除する際、 delete演算子で各オブジェクトの メモリ解放をプログラムしています。 例) delete m_pLine; delete m_pSurface; しかしながら、これらポインタの中には、 アルゴリズム上、既にdeleteされているものもあるため、 既にdeleteしたオブジェクトを更に deleteしようとして 実行時エラーを生じてしまいます。 deleteする前に、 当該ポインタが既にdeleteされているかどうか 判定する関数等あれば if文で回避できると思うのですが、 何か良い方法がありますでしょうか? よろしくお願いします。

専門家に質問してみよう