Seg fault when delete a pointer to vector<int>

P

Piotr

I have a class 'Statistics' which has a private attribute
' vector<int>* _x;'

And in the destructor of the Statistics, I have this code to free the
memory:

Statistics::~Statistics()
{

if (_x) {
delete _x; // Seg fault here...
}
}

But I get a Seg. Fault when I execute the program.

Can you please tell me what did I do wrong?

Thank you.


(gdb) bt
#0 0x00248eaa in __gnu_cxx::__pool<true>::_M_reclaim_block () from
/usr/lib/libstdc++.so.6
#1 0x0250da84 in __gnu_cxx::__mt_alloc<int,
__gnu_cxx::__common_pool_policy<__gnu_cxx::__pool, true> >::deallocate
(this=0x9107474, __p=0xdadadada, __n=152471256) at mt_allocator.h:746
#2 0x0250daac in std::_Vector_base said:
::_M_deallocate (this=0x9107474, __p=0x91686d8, __n=0) at
stl_vector.h:123
#3 0x0250dacd in ~_Vector_base (this=0x91686d8) at stl_vector.h:109
#4 0x0250db0b in ~vector (this=0x9107474) at stl_vector.h:273
#5 0x0250caf2 in ~Statistics (this=0xbfd85ad8) at
Statistics.cpp:54
 
L

Luke Meyers

Piotr said:
I have a class 'Statistics' which has a private attribute
' vector<int>* _x;'

And in the destructor of the Statistics, I have this code to free the
memory:

Statistics::~Statistics()
{

if (_x) {
delete _x; // Seg fault here...
}
}

But I get a Seg. Fault when I execute the program.

Can you please tell me what did I do wrong?

Looks like _x isn't valid at the point where you try to delete it.
Would need to see the rest of the code dealing with _x to know how that
happened. Are you setting it? Attempting conversions? Deleting it
twice?
(gdb) bt
#0 0x00248eaa in __gnu_cxx::__pool<true>::_M_reclaim_block () from
/usr/lib/libstdc++.so.6
#1 0x0250da84 in __gnu_cxx::__mt_alloc<int,
__gnu_cxx::__common_pool_policy<__gnu_cxx::__pool, true> >::deallocate
(this=0x9107474, __p=0xdadadada, __n=152471256) at mt_allocator.h:746

Note the suspicious hex address. __p is likely to be the value of _x,
by my guess. Use your debugger to trace what's going on.

Luke
 
P

Piotr

Thank you. Can you please explain what you meant by 'Attempting
conversions?'

And I have set it somewhere, otherwise, the code won't execute, right?

Statistics::~Statistics()
{

if (_x) {
delete _x; // Seg fault here...
}

}
 
P

Piotr

Can you please tell me what is the right way to write the destructor if
i have a private attribute
of ' vector<int>* _x;' in my class?

class Statistic {
private:
vector<int>* _x;
};
 
L

Luke Meyers

Piotr said:
Thank you. Can you please explain what you meant by 'Attempting
conversions?'

Mucking about with typecasts, conversion operators, single-argument
constructors, operator=, etc. Basically just stuff that would make it
easier to mess up some fancy pointer hocus-pocus.
And I have set it somewhere, otherwise, the code won't execute, right?

Uh, no. If you never initialize _x, your program will (hopefully) seg
fault because you are attempting to delete memory pointed to by an
uninitialized address.
Statistics::~Statistics()
{

if (_x) {
delete _x; // Seg fault here...
}

}

What do you mean "if(_x)"? Don't you know whether it's null? Is it
possible that _x became null at some point? Is it really necessary for
there to be two destruction paths for _x and its referent?

If you want more help, you should post, I say again, the rest of the
code dealing with _x.

Luke

Luke
 
L

Luke Meyers

Piotr said:
Thank you. Can you please explain what you meant by 'Attempting
conversions?'

Argh... i wrote up a whole reply and lost it to the bit bucket... sigh.
Anyway, conversions. I mean mucking about with explicit casts, or any
of the various forms of implicit conversions.
And I have set it somewhere, otherwise, the code won't execute, right?

Uh, no. If you haven't initialized _x, its contents are undefined,
which means it points to a random location of memory. What do you
suppose happens when you try to delete a pointer like that?
Statistics::~Statistics()
{

if (_x) {
delete _x; // Seg fault here...
}

}

Yup.

What's with the "if(_x)", by the way? Can x_ become null somehow? If
so, I'd reconsider your design not to have two destruction paths for
x_.

Luke
 
K

Kai-Uwe Bux

Piotr said:
Can you please tell me what is the right way to write the destructor if
i have a private attribute
of ' vector<int>* _x;' in my class?

class Statistic {
private:
vector<int>* _x;
};

You are asking for "the right way"? There is no such thing. It depends. The
most important question here is:

?? Can a pointee be shared among different objects of this class ??

a) If so, you will either need to be *very* careful or use a smart pointer
instead of a raw pointer. The reason is that you will want to delete
the pointer only if there are no other references to the same vector<int>
object left (rule: the last pointer pointing there has to kill it).

b) If not, you could and should just have a vector<int> member. In
this case, the default destructor of Statistic would take care of
the proper destruction of the member.

Note: Even if you did not intend the pointee to be shared, you may have
implemented the copy constructor or assignment operator in a way that
shares the pointee. The default copy constructor and assignment operator,
for instance, will happily copy the pointer so that afterwards you have two
Statistic objects whose _x members point to the same vector<int>.

Rule of thumb: avoid pointer members. They just cause a headache. If you
need them some reason, consider using something like tr1::shared_ptr
(formerly known as boost::shared_ptr).


Best

Kai-Uwe Bux
 
J

Jacek Dziedzic

Piotr said:
I have a class 'Statistics' which has a private attribute
' vector<int>* _x;'

And in the destructor of the Statistics, I have this code to free the
memory:

Statistics::~Statistics()
{

if (_x) {
delete _x; // Seg fault here...
}
}

But I get a Seg. Fault when I execute the program.

Can you please tell me what did I do wrong?

First of all, the 'if' part is unnecessary -- delete
works fine for NULL pointers.

Second of all -- I'd bet that either
a) you don't allocate _x with new,
b) you had already deleted _x earlier,
c) you have corrupted _x.

Try inserting some 'cerr << "I am here" << endl;'
constructs into sensitive places, like the destructor
or the place where you actually new your _x.

HTH,
- J.
 
D

David Harmon

On 29 Jan 2006 22:08:13 -0800 in comp.lang.c++, "Piotr"
Can you please tell me what is the right way to write the destructor if
i have a private attribute
of ' vector<int>* _x;' in my class?

The right way? The right way is to change it to
vector<int> x;

Then let the vector destructor handle it.
 
D

Daniel T.

"Piotr said:
I have a class 'Statistics' which has a private attribute
' vector<int>* _x;'

And in the destructor of the Statistics, I have this code to free the
memory:

Statistics::~Statistics()
{

if (_x) {
delete _x; // Seg fault here...
}
}

But I get a Seg. Fault when I execute the program.

Can you please tell me what did I do wrong?

Thank you.


(gdb) bt
#0 0x00248eaa in __gnu_cxx::__pool<true>::_M_reclaim_block () from
/usr/lib/libstdc++.so.6
#1 0x0250da84 in __gnu_cxx::__mt_alloc<int,
__gnu_cxx::__common_pool_policy<__gnu_cxx::__pool, true> >::deallocate
(this=0x9107474, __p=0xdadadada, __n=152471256) at mt_allocator.h:746

stl_vector.h:123
#3 0x0250dacd in ~_Vector_base (this=0x91686d8) at stl_vector.h:109
#4 0x0250db0b in ~vector (this=0x9107474) at stl_vector.h:273
#5 0x0250caf2 in ~Statistics (this=0xbfd85ad8) at
Statistics.cpp:54

My guess is that at some point in your code, you assign one Statistics
object to another. Here are a few things to try:

First:

Make sure _x is default initialized properly.

Statistics::Statistics():_x(0) { } or
Statistics::Statistics():_x(new vector<int>) { }

Second:

Make sure you aren't passing the pointer to other objects accidentally:

class Statistics {
// don't implement the two functions below
Statistics( const Statistics& );
Statistics& operator=( const Statistics& );
// other privates
public:
// public stuff
};

I have a feeling that when you put the two function definitions above
in, your code won't compile anymore. That tells you that you had
multiple Statistics objects sharing the same vector<int> object, the
first one to go out of scope deleted the vector<int> but the second one
doesn't know that so it tries to delete it again.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top