Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

error in std::vector 1

Status
Not open for further replies.

idgregorio

Programmer
Jul 5, 2005
1
0
0
FR
Hi,

The following code throws a segmentation fault at runtime and I can't figure out why. Perhaps somebody can help. The code defines a class X whose constructor takes an integer n and creates dinamically an array of n vector<int>(n). The destructor will free this memory. The class appears to work well, here it is:

#include <iostream>
#include <vector>

using namespace std;

class X{
public:
X(int n = 0);
~X();
private:
vector<int>* a_;
int n_;
};

X::X(int n): n_(n){
a_ = new vector<int>[n_](n_);
}

X::~X(){
delete[] a_;
a_ = NULL;}

Now I run into problems when I exercise my class in main(), more precisely, when I call the default copy constructor. The funny thing is that if do

int main(){
X x(5); // array of 5 elements, in fact the
// program works fine for 1,2,3 and 4
X y = x;
return 0;}

everything works fine but if I do

int main(){
X x(6); // 6 elements (same for 7, 8, ...)
X y = x;
return 0;}

I get the following error (from the vector destructor) at runtime:

Program received signal SIGSEGV, Segmentation fault.
0x08048b48 in ~vector (this=0x9b956e0) at stl_vector.h:375

A final note is that I'm using g++ and stl from GNU. Is it my fault that this program doesn't work?

Best regards.
 
Your problem has nothing to do with vector. It has to do with the way you are managing your dynamic memory. You create an array of objects dynamically in the constructor (in this case the objects are vectors). You delete this array in the destructor.

That is fine, however, in your main() function, you make a copy of your X object and place it into the y variable. Since you have not defined a copy constructor or copy assignment operator, the compiler just copies each member of the class. In this case, it makes a copy of your pointer to dynamic memory (a_) and places that pointer in the new instance.

At that point you have two different class instances, x and y, that both contain the same pointer to dynamic memory. When each of the these instances go out of scope, their destructors are called. This means that the same memory is deleted twice, which causes the seg fault.

You should always check to see if your class needs a copy constructor and copy assignment operator (operator=). Often if you need to write your own destructor, you need to write your own copy functions. One solution to your problem is to go ahead and implement the copy constructor and copy assignment operator. In this case the copy functions would allocate a new array of vectors and copy the data instead of just copying the pointer.

Another, better option, is to just use a vector instead of an array. You should just have a vector of vectors instead of a dynamic array of vectors. Then you won't even need the copy constructor, copy assignment operator, or destructor. Here is your declaration of a_ and your constructor using a vector of vectors:
Code:
vector<vector<int> > a_;
Code:
X::X(int n): a_(n, vector<int>(n)), n_(n){ }
You could also use a smart pointer class like boost::shared_array, although I think vector would probably be easier here.
 
In addition to what's already been said:
When using dynamic memory, make sure to always create the following functions (and ensure they do proper memory managment):
- copy constructor- to do deep copy
- assignment operator - to do clean up of old data, and deep copy the new data
- destructor - to clean up allocated memory

In programming in general:
- SELECT is not borken - It is rare to find a tested library call that doesn't work properly in a stable enviroment. The people writting the libraries have been doing it for a VERY long time, and when a problem happens everyone jumps on it and posts about it, and it gets fixed. If the compiler reports an error, or you think a library is broken for other reasons, then it's time to RTFM and look at how you are misusing the library.

In posting for help.
- Use the code tag It's easy to do and it makes it easier for us to read and help you.

[plug=shameless]
[/plug]
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top