7

単純なクラス コンストラクターを動作させるのに問題があります。

// In XModule.h
class XModule
{
...
public:
  TXMHeader     header;     // module header
  TXMInstrument*    instr;      // all instruments (256 of them)
  TXMSample*        smp;        // all samples (256 of them, only 255 can be used)
  TXMPattern*       phead;      // all pattern headers (256 of them)
}

モジュール.cpp

// In XModule.cpp
....
XModule::XModule()
{
  // allocated necessary space for all possible patterns, instruments and samples
  phead = new TXMPattern[256]; // Line # 1882
  instr = new TXMInstrument[256];
  smp = new TXMSample[MP_MAXSAMPLES];

  memset(&header,0,sizeof(TXMHeader));

  if (instr)
    memset(instr,0,sizeof(TXMInstrument)*256);

  if (smp)
    memset(smp,0,sizeof(TXMSample)*MP_MAXSAMPLES);

  if (phead)
    memset(phead,0,sizeof(TXMPattern)*256);

}
....

Extractor.cpp

#include "Extractor.h"
#include "XModule.h"

#include <iostream>
using namespace std;

int main ()
{
  XModule* module = new XModule();
  SYSCHAR* fileName = "Greensleeves.xm";

  ...

  return 0;
}

valgrind で実行すると、次のエラーが発生します。

==21606== Invalid write of size 8
==21606==    at 0x408BD3: XModule::XModule() (XModule.cpp:1882)
==21606==    by 0x4012D8: main (Extractor.cpp:9)
==21606==  Address 0x64874f0 is not stack'd, malloc'd or (recently) free'd

行の後半ではmemset(instr,0,sizeof(TXMInstrument)*256);pheadinstrおよびsmp.

gdb をステップ実行すると、その前にpheadinstr、およびsmpが正しく設定されていることが明らかになりましたが、配列ポインターのアドレスは、新しい配列に割り当てられた領域内にありますinstr。調べてみる&pheadと、これは事実であることが判明しました。

instr = new TXMInstrument[256];に使用されるメモリ領域を割り当てるための呼び出しが新しくなるのはなぜですか? またphead、これを修正しinstrたりsmp、問題をさらに診断するにはどうすればよいですか?

4

1 に答える 1

9

クラス定義にたくさんの #IFDEF があることが判明したため、プロジェクトの makefile でビルドされたライブラリに対してユーティリティをコンパイルしていたときに、ソース ヘッダーを使用していて、クラスが異なる量のプロパティを持っていると考えたので、それらはメモリに正しく配置されておらず、配列の割り当てによって押しつぶされました。

プロジェクト ライブラリを使用せず、ソース ファイルを新しいフォルダーにコピーし、g++ *.cpp.

于 2012-04-06T05:01:22.867 に答える