Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Invalid Write of Size 8 at first line in class constructor

Tags:

c++

valgrind

I'm having trouble getting a simple class constructor to work.

// 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)
}

Module.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;
}

When I run with valgrind I get the following error:

==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

The later in the line memset(instr,0,sizeof(TXMInstrument)*256); it zeroes out phead, instr and smp.

Stepping through with gdb revealed that phead, instr, and smp are set correctly, before that, but the addresses of the array pointers are within the area that new allocated for the instr array. Examining &phead revealed this to be true.

Why does new the call to instr = new TXMInstrument[256]; assign memory space that is used for phead, instr and smp and what can I do to fix this or further diagnose the issue?

like image 897
Daniel X Moore Avatar asked Apr 04 '12 23:04

Daniel X Moore


1 Answers

It turns out there were a bunch of #IFDEFs in the class definition, so when I was compiling my utility against the library built with the projects makefile it was using the source headers and thought the class had a different amount of properties, so they were not arranged in memory correctly and got crushed by the allocation of the arrays.

I solved it by not using the projects library, copying the source files to a new folder, and running g++ *.cpp.

like image 76
Daniel X Moore Avatar answered Oct 25 '22 07:10

Daniel X Moore