- 題名: ヒープが壊れるエラー
- 日時: 2011/04/09 12:08:58
- ID: 28420
- この記事の返信元:
- (なし)
- この記事への返信:
- [28424] Re[1]: ヒープが壊れるエラー2011/04/09 17:01:38
- ツリーを表示
ありがとうございます。
> どうしてそのように判断したのでしょうか?
ドロップ側には文字列データが渡っていました。
> HGLOBAL は GlobalAlloc を使って確保するものです。
> それに対して変なポインタを与えているので、それを GlobalSize を与えたので不正なポインタ操作になっていると考えられます。
以下のように修正しました所、
・テキストエディタにドロップした場合
・ダイアログ内の何もない個所でドロップした場合
では、エラーが出ず、うまくドロップされたデータを渡すことができるのですが、
C#で作成したフォームにドラッグしてデータがわたるか確認したところ、
データを取得した後に、エラーが出てしまいます。
【エラー内容】
ヒープが壊れていることが原因として考えられます。XXX.exeまたは読み込まれたDLLにバグがあります。
【エラーの出る関数(dbgheat.c)】
extern "C" _CRTIMP int __cdecl _CrtIsValidHeapPointer(
const void * pUserData
)
VCダイアログからC#のフォームにドラッグアンドドロップすると、データ受け取り後にエラーが出ますが、
C#フォームからVCダイアログにドラッグアンドドロップすると上手くいきます。
【修正したドラッグ側のソース】
void TestDlg::OnLvnBegindragList(NMHDR *pNMHDR, LRESULT *pResult)
{
LPNMLISTVIEW pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR);
// TODO: ここにコントロール通知ハンドラ コードを追加します。
HGLOBAL hGlobal;
hGlobal = GlobalAlloc(GHND,10); // DnDするデータ領域を作成
char* ptr= (char*)::GlobalLock(hGlobal);
strcpy(ptr, "ABC");
::GlobalUnlock(hGlobal);
COleDataSource dataSource; // データソースオブジェクトをインスタンス化
dataSource.Empty();
dataSource.CacheGlobalData(CF_TEXT, hGlobal); // 作成したデータを設定
DROPEFFECT result = dataSource.DoDragDrop(DROPEFFECT_COPY|DROPEFFECT_MOVE);
if( result == DROPEFFECT_MOVE ) {
delete hGlobal;
}
*pResult = 0;
}
> なぜ、このようなコードを書いているのでしょうか? > GlobalAlloc の説明ページを読んでいますか? すみません、よく見たら書いてありましたね。 delete hGlobal;から ::GlobalFree(hGlobal); に直しました。 今までのエラーはでなくなったのですが、 VCからC#フォームへドラッグドロップを実行すると、以下のエラーが 出てきました。 Debug Assertion Failed! Program: ... File: f:\dd/vctools\vc7libs\ship\atlmfc\src\mfc\cmdtarg.cpp Line: 43 For information on how your program can cause an assertion failure, see the Visual C++ documentation on asserts. これは、GlobalFreeのMSDNの説明ページにある文↓のことなのでしょうか? リリースで実行すると出てきません。 アプリケーションがデバッグ版の環境で動作している場合、GlobalFree は、ロック済みのオブジェクトを解放しようとするときに、そのことを知らせるメッセージを発行します。 アプリケーションをデバッグしている場合、GlobalFree はロック済みオブジェクトを解放する直前のブレークポイントに入ります。 この結果、この動作が意図したものであるかどうかを確認し、実行を続けることができます。
自己解決いたしました。
http://rararahp.cool.ne.jp/cgi-bin/lng/vc/vclng.cgi?print+201011/10110009.txt
こちらを参考にして
COleDataSource* dataSource = new COleDataSource();
dataSource->DoDragDrop();
dataSource->InternalRelease();
と、DoDragDrop()後に、InternalRelease()したところエラーが出なくなりました。
ありがとうございました。
分類:[.NET]
こんにちは、現在MFCでOLEのドラッグ&ドロップの動作を作成しているのですが、 文字列をドラッグしてテキストエディターにドロップすると以下のエラーが出てきてしまいます。 【エラー内容】 ヒープが壊れていることが原因として考えられます。XXX.exeまたは読み込まれたDLLにバグがあります。 ドラッグしている文字列はきちんと取れているように思います。 何か解決する方法はないでしょうか。 【ドラッグ側のソース(リストコントロールのイベントにしています)】 void TestDlg::OnLvnBegindragList(NMHDR *pNMHDR, LRESULT *pResult) { LPNMLISTVIEW pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR); // TODO: ここにコントロール通知ハンドラ コードを追加します。 HGLOBAL hGlobal; // DnDするデータを作成 hGlobal = "ABC"; COleDataSource dataSource; // データソースオブジェクトをインスタンス化 dataSource.CacheGlobalData(CF_TEXT, hGlobal); // 作成したデータを設定 DROPEFFECT result = dataSource.DoDragDrop(DROPEFFECT_COPY|DROPEFFECT_MOVE); if( result == DROPEFFECT_MOVE ) { delete hGlobal; } *pResult = 0; } 【エラーの出る箇所(1)(olemisc.cpp)】 テキストエディタにドロップした場合 AFX_STATIC HGLOBAL AFXAPI _AfxCopyGlobalMemory(HGLOBAL hDest, HGLOBAL hSource) { ASSERT(hSource != NULL); // make sure we have suitable hDest ULONG_PTR nSize = ::GlobalSize(hSource);←●ここを実行する際にエラー発生 if (hDest == NULL) { hDest = ::GlobalAlloc(GMEM_SHARE|GMEM_MOVEABLE, nSize); if (hDest == NULL) return NULL; } //-----------------------以下省略-------------------------- 【エラーの出る個所(2)(oledobj2.cpp)】 ダイアログ内の何もない個所でドロップした場合 void COleDataSource::Empty() { if (m_pDataCache != NULL) { ASSERT(m_nMaxSize != 0); ASSERT(m_nSize != 0); // release all of the STGMEDIUMs and FORMATETCs for (UINT nIndex = 0; nIndex < m_nSize; nIndex++) { CoTaskMemFree(m_pDataCache[nIndex].m_formatEtc.ptd); ::ReleaseStgMedium(&m_pDataCache[nIndex].m_stgMedium);←●ここを実行の際にエラー } //-----------------------以下省略--------------------------