Link to home
Start Free TrialLog in
Avatar of skp23
skp23

asked on

C++ memory overwrited by operator new

I have writen a class BooleanString, below is the header file.
class BooleanString
{
 public:
  BooleanString(int strLength);
  ~BooleanString();

  bool getVal(int index);
  void setVal(int index, bool indexVal);
  void setAll(bool indexVal);

 private:

  char* myBooleanString;
  int myStringLength;
  int numChar;
}

In the main program I have the following codes.

int main()
{
  BooleanString myBoolStr(30);
  int* arrayA;
  int* arrayB;
  ...

  Do some op with myBoolStr;
  arrayA = new int[40];
  ...
}

The program keep giving me incorrect output, I have located the error. It seem that if I comment out the line

arrayA = new int[40];

the problem will be solved. In fact I have try to comment out rest of program and print out the result of myBoolStr before and after the "new" statement following it. The two output are not the same. Therefore I conclude that the new statement is overwriting the memory location of myBoolStr.  

Did anyone had simular experience? If so how was it solved? For some more background I'm using a Sun Ultra 10 running KDE, and I compile the program with g++.
Avatar of Chase707
Chase707

There is obviously a bug in your code.  chances are that you are not allocating enough memory for your BooleanString, and new int is overwriting the memory that you should have allocated.   we need to know more specifics.  Post the code for your constructor of BooleanString, and this code:

// Do some op with myBoolStr

Post the code for output, and describe how is the output wrong.
Chase707 seems to have it right. Where is the constructor for BooleanString and how to you print the values? Those two functions would help in narrowing down the error.

-bcl
Avatar of skp23

ASKER

The constructor for the BooleanString is as follows:

BooleanString::BooleanString(int strLength)
{

  myStringLength = strLength;
  numChar = strLength / 8;
  if (strLength % 8 != 0)  
  {
    numChar = numChar + 1;
  }

  myBooleanString = new char[numChar];
  myBooleanString[0] = 'Z';
}

Each boolean type is allocated 1 bit.
Other operations are too long to post here, but it involved in using the member functions of edit the bit value of myBooleanString.
The output is (1 = true, 0 = false)

100100000010000000000000000010000001
000000000000001001010001101010000001

The first line is the correct output, the second line should be the same as the first line. The first line is outputed before the "new" operator is used, the second line is outputed immediately after the line with "new" operator.

Another note, this overwriting problem will not occure if

ArrayA = new int[2];

any value above 2 will cause the overwriting. If I didn't allocate enough space for BooleanString is the cause, it does not explain why 2 and below will not change the value.

Another problem is with the code I didn't show, I actually called 2 function in there, the overwriting only occures if I call one of the function, but when I call both function the overwriting occures.
So in setVal you check the index and set the appropriate value:

void setVal(int index, bool indexVal) {
  assert(index < myStrLength);
  int myChar = index / 8;
  int offset = index % 8;
  char myBit = 1 << offset;
  if (indexVal)
    myBooleanString[myChar] |= myBit;
  else
    myBooleanString[myChar] &= ~myBit;
}

The assertion shown above should help you track down where you write past the length...

Note that only the left-most bit (in printing) is still set correctly. That makes me wonder about the values of some of the variables. Do you print numChar? Is it 4?

Just wondering, why set the low byte to 'Z'?

-bcl
Okay, right-most byte is unchanged and I have problems with directions.

-bcl

My observation, this output is 36 bits long, but you are allocating only 32 bits for your BooleanString

100100000010000000000000000010000001

BooleanString myBoolStr(30); // <---- your boolean string is only 4 bytes long, ie 32 bits

Avatar of skp23

ASKER

I have located the error to the following code.

#include "BooleanString.h"

void outBool(BooleanString inputBool, int strSize);

int main()
{
  int i;
  BooleanString myString(12);
  int* makeMeMad;
  int* Dist;
  int temp;
  myString.setAll(false);
  for (i = 0; i < 12; i=i+2)
  {
    myString.setVal(i, true);
  }
  outBool(myString, 12);
  Dist = new int[12];            //problem line
  outBool(myString, 12);
  return (0);
}

void outBool(BooleanString inputBool, int strSize)
{
  int i;
  cout << "  ";
  for (i = 0; i < strSize; i++)
  {
    cout << inputBool.getVal(i) << " ";
  }
  cout << endl;
}

In the above example if I comment out the trouble line everything works fine. The output is
1 0 1 0 1 0 1 0 1 0 1 0
0 0 0 0 0 0 0 0 0 0 0 0
The second line should be same as first line.
The reason I set it 'Z' is because if I remember correctly it will give the binary value 255, anyway it was not important, and I have deleted that line.

The following is my setVal and getVal function.

bool BooleanString::getVal(int index)
{
  int charNum;
  int bitNum;
  char temp;

  if (index < 0)
  {
    cout << "Input to BooleanString::getVal cannot be negative"
      << endl;
    return (false);
  }

  if (index >= myStringLength)
  {
    cout << "Input to BooleanString::getVal exceed length"
         << endl;
    return (false);
  }

  charNum = index / 8;
  bitNum = index % 8;
  temp = myBooleanString[charNum];

  temp = temp >> 7 - bitNum;
  temp = temp << 7;
  temp = temp >> 7;

  //  cout << (int)temp << endl;  

  if ((int)temp == 0)
  {
    return (false);
  }
  else if ((int)temp == -1)
  {
    return (true);
  }
  else
  {
    cout << "wrong result" << endl;
    return (false);
  }
}

void BooleanString::setVal(int index, bool indexVal)
{
  int charNum;
  int bitNum;
  char temp;
 
  if (index < 0)
  {
    cout << "Input to BooleanString::setVal cannot be negative"
      << endl;
  }

  if (index >= myStringLength)
  {
    cout << "Input to BooleanString::setVal exceed length"
      << index << " " << myStringLength
         << endl;
  }

  charNum = index / 8;
  bitNum = index % 8;

  if (indexVal == true)
  {
    temp = 0x01;
    temp = temp << 7 -  bitNum;
    myBooleanString[charNum] = myBooleanString[charNum] | temp;
  }
  else
  {
    temp = 0x01;
    temp = temp << 7 - bitNum;
    temp = ~temp;
    myBooleanString[charNum] = myBooleanString[charNum] & temp;
  }
}
ASKER CERTIFIED SOLUTION
Avatar of Chase707
Chase707

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of skp23

ASKER

May be there is something wrong with the O/S or compiler then, anyways thank you for the input.