newしたものをdeleteした時に失敗 – プログラミング – Home

newしたものをdeleteした時に失...
 
通知
すべてクリア

[解決済] newしたものをdeleteした時に失敗


じゃこ
 じゃこ
(@じゃこ)
ゲスト
結合: 17年前
投稿: 13
Topic starter  

いつもお世話になっております。
私、かなりのMFC初心者ですが、よろしくお願いします。

WinXP SP2
V6.0 MFC 使用です。

EXEのソース内でnewしたクラスを別のDLLの関数内でdeleteしています。
EXE側のプロジェクトでデバッグをしているとDLLの関数内のdeleteの箇所で勝手に
ブレイクポイントが立ち、Invalid Address specified to RtlValidateHeapの
メッセージがアウトプットに表示されます。

何故かこの現象が、DLLが「Win32 Release」でビルドしたDLL時のみ発生します。
リリース版でビルドした時のみ発生するので、今の所、製品版として問題無いの
ですが、デバッグで毎回ブレイクポイントが立つのと、たんに運良く動作している
気がしてなりません。

newで確保したアドレスと、delete時のアドレスが一致するのは確認しました。

MFC初心者の為、何故こういった事になるか理解に苦しんでいます。
よろしくお願いします。

・サンプルソース
(量が多い為、実ソースでありませんが、こういった構成になっています)
(myClassは別DLLになっています)

VOID CMyExe::Main()
{
CMyClass myClass;
CMember *pMember = new CMember ();

// メンバー追加
myClass.Append (pMember);

// メンバー削除
myClass.Empty ();
}

VOID myClass::Append (CMember *pMember)
{
m_pMember = pMember;
}

VOID myClass::Empty()
{
delete m_pMember; // ここでブレイクポイントが立ちます
}


引用未解決
トピックタグ
Blue
 Blue
(@Blue)
ゲスト
結合: 20年前
投稿: 1467
 

単に、リンクしているlibやヘッダファイルに相違があるだけとか。


返信引用
じゃこ
 じゃこ
(@じゃこ)
ゲスト
結合: 17年前
投稿: 13
Topic starter  

Blueさん、ありがとうございます。
そもそも何でdeleteの箇所でInvalid Address specified to RtlValidateHeapの
メッセージが出力されるのかが分からないんですよね。
debugモードでnewしたものをreleaseモードでdeleteしても問題無いと思うのですが・・・


返信引用
Blue
 Blue
(@Blue)
ゲスト
結合: 20年前
投稿: 1467
 

DLL側のクラスのメンバ変数や仮想関数を増やしたりすると、
古いままのヘッダやlibを使っていると、確実にメモリ面で相違が出ます。
(たとえば、メンバ変数にint型の値を追加しただけで、他のメンバ変数の
参照位置がずれるとか。)

>debugモードでnewしたものをreleaseモードでdelete
そのようなつくりは出来ないと思いますけど。

ReleaseでNGでDebugでOKってことは、よくありうると思います。
(メモリの初期化等)
ReleaseとDebugの違いを調べてみてはどうでしょうか?


返信引用
ITO
 ITO
(@ITO)
ゲスト
結合: 22年前
投稿: 1235
 

Debugは、特にメモリー操作の場合はNGにならないように動くことがあるみたいです。
僕も経験あるのですが、理由は良くわかりません。
debugモードのDUMP表示にメモリーリーク等、何かでていないですか?

ここのところが気になります。
>EXEのソース内でnewしたクラスを別のDLLの関数内でdeleteしています。
new - deleteは同じルーチンで行わないとまずいと思います。
普通は、EXE側でnewしたならEXE側の終了処理のところでdeleteします。
DLL側はあくまでもEXE側でnewしたクラスを参照・継承等で使用するだけにしたほうが
いいと思います。
逆に、DLL側でnew-deleteする方法もあると思いますが、EXE側との関連があるので
難しいと思います。


返信引用
じゃこ
 じゃこ
(@じゃこ)
ゲスト
結合: 17年前
投稿: 13
Topic starter  

Blueさん、ITOさん、ありがとうございます。

Blueさん
ヘッダやLIBファイルは確認しました。問題無いハズなのですが・・・。

>そのようなつくりは出来ないと思いますけど。
言葉足らずですいません。
「debugモードのEXEでnewしたものをreleaseモードのDLLでdeleteした」でした。

ITOさん
>debugモードのDUMP表示にメモリーリーク等、何かでていないですか?
debugモード時は何も出てきません。
やはり、newとdeleteは同じEXEかDLLでしないといけないと言う事でしょうか?


返信引用
Blue
 Blue
(@Blue)
ゲスト
結合: 20年前
投稿: 1467
 

>やはり、newとdeleteは同じEXEかDLLでしないといけないと言う事でしょうか?
そうすべきでしょう。

参考)
http://forums.microsoft.com/MSDN-JA/ShowPost.aspx?PostID=1702483&SiteID=7


返信引用
ITO
 ITO
(@ITO)
ゲスト
結合: 22年前
投稿: 1235
 

>やはり、newとdeleteは同じEXEかDLLでしないといけないと言う事でしょうか?
buleさんの意見にあるとおりに、そうすべきだと思います。
たとえ、
 buleさんの紹介されたサイトより、
「LocalAlloc/GlobalAlloc や CoTaskMemAlook などの APIベースの
  メモリ確保を行う必要があります。
メモリの開放は、LocalFree/GlobalFree や CoTaskMemFree などを
用いる必要があります。」
に変更したとしても、
1. DLLが勝手に開放してしまったクラスををEXEで使ってしまう。
2. 未だEXEで確保していないクラスをDLLで使用してしまう。
この2項目が完全にないということならばまだいけるかも知れませんが
かなり難しいと思います。


返信引用
じゃこ
 じゃこ
(@じゃこ)
ゲスト
結合: 17年前
投稿: 13
Topic starter  

BLUEさんのMSDNへのリンク、大変為になりました。
ありがとうございます。

BLUEさんとITOさんが言われるとおり、同じDLL内で処理したいと思います。
既に出来上がってるシステムなので、猛烈に大変ですが・・・(^_^;)

ありがとうございました。大変勉強になりました。
私一人ではとても解決出来なかったと思います。


返信引用

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました