私はこれについて頭を悩ませています。これは、私だけが見ることができれば本当に簡単な答えがある問題の1つか、あいまいな落とし穴の1つです。問題は、ある関数で構造体オブジェクトを新規作成し、ポインターをデキューに保存し、そのポインターを別の関数で取得し、構造体のデータが使用されたら、ヒープ上のオブジェクトを削除しようとしていることです。すべてが 1 つのクラス インスタンスで発生します。それをすると、私は爆弾を手に入れます。理由がよくわかりません。これは、作成時および取得後の有効なポインターです。書き込み/読み取りができます。しかし、それを削除しようとすると、da bomb が発生します。
//This creates and saves the heap object
void CFoo::QueueEvent( TICKTYPE& tp )
{
TICKTYPE* pTt = new TICKTYPE;
memcpy( pTt, &tp, sizeof(tp) );
m_queuedevents.push_front( pTt );
}
//This retrieves it
int CFoo::ReplayQueuedEvents()
{
long lSz = m_queuedevents.size();
for( int i = 0; i < lSz; i++ )
{
TICKTYPE Tt;
TICKTYPE* pTt = m_queuedevents.back();
//m_queuedevents.pop_back(); //bombs w or w/o this
//bombs w ot w/o memcpy
memcpy( &Tt, pTt, sizeof( *pTt ) );
//int iRtn = SendEvent( Tt );
ASSERT( SendEvent( Tt ) != ERR_FAILURE );
//This asserts before or after the memcpy.
delete[] pTt;
//delete pTt;
}
}
パート2
ご提案いただきありがとうございます。
削除[]と削除
私は必死だったので、delete[] も試してみましたが、それはたまたまコピーしたものでした。私は2か所で削除を試みましたが、それでも動作します。
「TICKTYPEを表示」
私は TICKTYPE を表示しますが、今見てみると、内部に少なくとも 2 つの他の構造体への参照があり、かなり単純なものからかなり複雑なものに成長しています。数ページのコードを投稿(およびフォーマット)する必要があります。以下のコメントに基づいて、それをクラッシュの原因として調べてみます。ありがとうございました。
「削除する前に pTt が有効かどうかを確認してください。」
削除する前に読み書きを試みましたが、すべて問題ないようです。また、Vis Stud は、削除する直前に構造体に有効なデータを表示します。これをさらに研究するときは、これを念頭に置いておきます。
「3のルール」
ああ、まあそうかもしれません。
まだ解決策はありませんが、解決したら投稿します。皆さんは良いアイデアをいくつか提供してくれました。もう頭を悩ませることはありません。ひざまずいて仕事をするだけです。乞うご期待...
再度、感謝します。(PS 'da bomb' は通常は良いことですが、英語の美しさは、単語を構成しても要点を伝えることができることです' より正確ではあるが退屈な用語は、GPF、ASSERT などでした。対処するときにこれらが必要です。ときどき C++ を使って... :) ここでコーディングの心理学について話す人は誰もいません..笑.")
パート 3
問題はmemcpyにあることがわかりました。すべての memcpy を取り出すと、オブジェクトが削除されます。ただし、コピーの問題が残ります。参照 TICKTYPE& tp からポインター TICKTYPE* pTt に移動する必要があります (QueueEvent を参照)。
以下のクールな提案に従って Copy コンストラクターを作成してみました。この問題は、次のような従来の copy-ctor が使用されている場合に返されます。
TICKTYPE( TICKTYPE const& ref )
{
a = ref.a;
b= ref.b;
c = ref.c;
d= ref.d;
e = ref.e; //etc...
}
メイン構造体の内部にはディープ コピーされる構造体がいくつかあり、MSFT 構造体の FILETIME と SYSTEMTIME がいくつかありますが、それらが既にコピー ctor を持っているかどうかはわかりません。
次に、ref から ptr への移行の問題があります。署名入りコピー機をやってみた
TICKTYPE* ref;
それから
pTt = rTt
ここで、pTt は TICKTYPE* で、rTt は TICKTYPE rTt です。それはコンパイルされませんでした。
質問
他の構造体を含む構造体を ref から新しいポインター var (スタックからヒープ) にコピーする最良の方法は何ですか? より永続的なストレージのために、そのデータをスタックからヒープに移動したいと考えています。
memcpy によってコピーされた構造体にストラットが埋め込まれないように、各構造体レベルの mem コピーを行うことを考えていました。どう思いますか?良いアプローチですか?
パート 4
回答者の皆様に改めて感謝いたします。あなたのアドバイスは非常に役に立ちました。この問題は、最上位構造体の memcpy を実行するときに作成されました。メインの最上位構造体の内部で下位構造体の memcpy を実行しても、下位構造体がない限り、delete が失敗することはありませんでした。下位の構造体で memcpy を使用し、最上位の構造体で変数コピーによる変数を使用しました。こんな感じです
TYPE1 foo1;
foo1.a = foo.a
foo1.b = foo.b
foo1.c = foo.c
memcpy( foo1.d, foo.d, sizeof( foo.d) );
memcpy( foo1.e, foo.e, sizeof( foo.e) );
等
それはうまくいきます。他の方法ほどエレガントではないかもしれませんが、当分の間機能するか、機能するように見えます。すべてがメインコード本体に明確に文書化されており、何が起こっているのか、その利点があります。