0
class SimpleVariant
{
public:
    SimpleVariant()  { /*...*/ };
    // ...
};


struct VariantBlock
{
    int nRows, nCols;
    vector<SimpleVariant> theData;
};



void dumbFunction( VariantBlock& theBlock, int nRows, int nCols )
{
    // ...
    cout << "theBlock.nRows= " << theBlock.nRows 
         << ", theBlock.nCols= " << theBlock.nCols
         << ", theBlock.theData.size() " << theBlock.theData.size();

    theBlock.theData.resize( nRows * nCols );   
       // throws Access Violation Exception

    // ...
} 

出力は、nRows = 61、nCols = 5、size()= 0を返します。これは、アクセス違反例外がスローされる前のその時点での正確な値です。

私はMSVC6を使用していますが、これは明らかに最適ではありませんが、現時点では選択の余地はありません。

4

3 に答える 3

2

最近、元々Visual C ++ 6用に記述されたコードをアップグレードする必要がありました。そのコードには、VC++6が参照に正しくバインドできるものを処理できないという問題がありました。これは暗闇の中でのショットのようなものですが、あなたはに渡していconst VariantBlockますdumbFunctionか?C ++のルールでは、それは違法ですが、VC++6ではそれが間違っているのではないかと強く思います。

もう1つの可能性は、ある種の実行時の不一致です。(1)がVariantBlock1つのモジュールに割り当てられ、(2)dumbFunctionが別のモジュールからのものであり、(3)それらが異なる設定、場合によっては異なるバージョンのコンパイラでコンパイルされた場合、このような動作が見られます(resize()新しいメモリ、すべてをそこにコピーしてから、古いメモリの割り当てを解除します。ただし、古いメモリは別のランタイムに割り当てられているため、プログラムはバーフします)。

要するに、あなたが投稿したコードは完全に問題ありません。他に何かが起こっています。

于 2011-03-26T08:02:04.193 に答える
1

そのエラーの前に何か間違ったことをしたと思います。操作でメモリが要求されstd::vector::resize、ヒープが破損しやすい。未定義の動作の悪い点は、エラーの後に 100 万回実行された命令で症状が現れる可能性があることです (つまり、「何でも起こり得る」には「何も起こらない」が含まれます)。

グローバル アロケータを再定義し、破損の多くのチェックを実行できる「デバッグ メモリ マネージャ」があります。

  1. 割り当てられたメモリを明確でないビット パターンで初期化します (これは、誰かが初期化されていないメモリを使用し、明らかにコードがゼロを見つけたときに機能する場合の問題を特定するためです)。
  2. すべてのメモリ ブロックの前後に「安全領域」を追加し、削除時に上書きされていないことを確認します (これはバッファ オーバーランの検出のためです)。
  3. 解放時に別の特定のパターンでメモリを埋めます (これは、削除後の読み取りエラーをキャッチしようとするためです)
  4. メモリ ブロックを再利用し、再割り当て時またはグローバル検証時に、削除されたメモリ パターンがまだ存在することを確認します (これは、削除後の書き込みエラーをキャッチするためです)。
  5. __FILE__/__LINE__誰がメモリ リークをリークしているかを検出し、削除後に破損したブロックを誰が使用していたかを知ることができるように、すべてのブロックに情報をマークします。

また、オンデマンドですべてのメモリ ブロックを調べて一貫性をチェックできるメモリ チェック ルーチンもあります (通常は、割り当て/割り当て解除のみをチェックします)。絶望的な場合のために、メモリのすべての割り当て/割り当て解除の完全なリストをログアウトすることもできます。

残念なことに、ポイント (5) C++ 構文はインストルメント化が難しいため、実際には使用しませんnewが、xnew最終的に配置割り当てに展開されるマクロを使用します。これは、標準ライブラリ内で割り当てられたメモリ ブロックを計測できないことも意味します (ただし、ライブラリ内で割り当てが行われる前に、プログラム内で割り当てを行った最後のソース行を保存します)。

于 2011-03-26T08:30:34.840 に答える
1

私はOPです。

問題は、呼び出し関数からのメモリ破損でした。

于 2011-03-26T10:43:22.323 に答える