new operator gives back same address

Hi all,
I have a method in which I create some objects using 'new' operator:

 
idealTrack = new SbtTrack( aListOfPoints, SbtEnums::idealTrack );


In the distructor I was receiving this error:


*** glibc detected *** double free or corruption (fasttop): 0x0bafcd78 ***
Abort (core dumped)


after some iterations.

By printing the memoery address given back by 'new', I get:


adding an ideal track: 0xbc03220
adding an ideal track: 0xbc03220


So 'new' operator is giving back an address twice... why does this happen?
I've checked the % of memory used by the program: hardly reaches 10% before crashing.

Any help is appreciated.

Many thanks in advance!

Regards,
Marco
It is happening because something is wrong with your code. Can you post more?
This is the c'tor I use in the example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
SbtTrack::SbtTrack(vector<SbtSpacePoint*> aSpacePointList,
                   SbtEnums::trackType type):
  _DebugLevel(0),
  _spacePointList(aSpacePointList),
  _chi2(0.0),
  _ndof(0),
  _trackType(type)
{
  if (_DebugLevel>0)  cout << "SbtTrack:  DebugLevel= " << _DebugLevel << "\n" ;
  //initiliaze the covariance matrix
  _CovX[0][0]=0; _CovX[0][1]=0;
  _CovX[1][0]=0; _CovX[1][1]=0;
  _CovY[0][0]=0; _CovY[0][1]=0;
  _CovY[1][0]=0; _CovY[1][1]=0;

  // sort the space points in ascending z position
  std::sort( _spacePointList.begin(), _spacePointList.end(), SbtSpacePoint::ltz );

  if (type == SbtEnums::idealTrack)
    {
      try {
        SetIdealTrackParms(_spacePointList.at(0),_spacePointList.at(1));
      }
      catch (std::out_of_range &) {
        std::cout << "Caught _spacePointList std::out_of_range\n";
        SetIdealTrackParms( NULL, NULL );
      }
    }

  // set default value for residaul
  for (int i=0; i< maxTrkNSpacePoint; i++){
    _residualX[i]=-999.0;
    _residualY[i]=-999.0;
    _recoX[i]=-999.0;
    _recoY[i]=-999.0;
    _fitX[i]=-999.0;
    _fitY[i]=-999.0;

  }
  // digi type are not produced at the moment for simulated tracks
  // track are produced directly from SpacePoints
  if (_trackType == SbtEnums::recoTrack ) SetIsOnTrack();
}


Thanks for looking into this...

Marco
(a) don't use _name, use name_ if you want. But leading underscores should be avoided (not all cases are reserved, but I don't know the exact rules and I'm pretty sure so do you...)
(b) The constructor has no possibility of changing the return value of new except for throwing an exception (I'm not sure if then the return value is 0 or undefined). So, in short, you posted the wrong code to solve your problem ;-)
(a) don't use _name, use name_ if you want. But leading underscores should be avoided (not all cases are reserved, but I don't know the exact rules and I'm pretty sure so do you...)

It is written in our coding guidelines to use '_' prefix for data members... now I am puzzled...

Anyway:

(b) The constructor has no possibility of changing the return value of new except for throwing an exception (I'm not sure if then the return value is 0 or undefined). So, in short, you posted the wrong code to solve your problem ;-)


I posted the c'tor I call via new.

This is the method (of a different class) that calls that constructor:

1
2
void GenerateTrack( SbtTrack*& simulTrack,
                                     SbtTrack*& idealTrack ) 


and in particular:

1
2
3
  if ( aListOfPoints.size() > 0 ) {
    idealTrack = new SbtTrack( aListOfPoints, SbtEnums::idealTrack );
  }


Many thanks,
Marco
It is written in our coding guidelines to use '_' prefix for data members

Well, your coding standard, like most I've seen, sucks. The problem: the standard only reserves leading-underscore-names in the global namespace (so it *should* be OK for members). BUT implementations tend to use macros, which don't observe namespaces, and I doubt that any implementation out there is really 100% compatible with this rule. So, avoid leading underscores and double underscores (see also Sutter: "Exceptional C++", p. 74, where I looked it up just for you to be sure I don't tell you something wrong ;-) ).

The rest of the code, if you use it seperately, should work. I don't see an error in it. But then again, it isn't much. Are you sure you don't try to delete the same pointer twice?
So 'new' operator is giving back an address twice...

New is implemented like
1
2
3
4
void* operator new(size_t s)
{
  return malloc(s);
}

so it really isn't anything the constructor can screw (except for overwriting this returned address... which is rather unlikely)
Last edited on
Well is the whole point of void not for functions that DONT return anything?
A pointer to void is a pointer to anything, and a pointer is something, so the function returns something. Heh...

The code is failing because somewhere you are trying to free something more than once. The error is likely in how you are using your class.

If I may be so bold as to think this, might you have something like the following?
1
2
3
4
5
6
7
8
9
class fooey
  {
  foo* quux;
  ...
  ~fooey()
    {
    delete quux;
    }
  }

This will cause you problems if you class is ever copy constructed. As soon as one of the copies is destroyed, you're dead in the water.
Duoas do you ever get stuck on anything... ever? lol
All the time. I've just been doing this stuff longer than some of you have been alive. :-)
Dear Duoas, I think you got the point.
I will try to explain what I'm doing:

1
2
3
4
5
6
7
8
9
10
11
class SbtEvent {
  vector<track*> someTracks_ ;
  
  ~SbtEvent()
    {
    for ( int i = 0; i < someTracks_.size(); i++ ) {
      delete _someTracks[i];
      someTracks_[i] = NULL;
     }
    }
  }


that looks similar to your example.
Infact we decided to clean up all the 'SbtTrack' in the 'SbtEvent'.

So you say that if I copy construct SbtEvent I will get in trouble...
But why I'm getting twice the same address?

Ah, many thanks!!!

Marco

PS @ exception: I have to stick to my boss' coding rules. But I will discuss them with him. <:-)
You get the same address twice since once you delete it the memory manager can now give it to the next new request.

You can implement a reference counter to track how many instances of the class are looking at the data. I did something similar here:
http://www.cplusplus.com/forum/general/2236/page1.html#msg8368

The Image2D's private ImageData structure keeps all the important information in a shared, dynamically-allocated, reference-counted piece of memory, so it is only deleted when all instances of the object are destroyed.

Hope this helps.
Topic archived. No new replies allowed.