stl vector: what is wrong with this code?

L

luigi

The following code causes crash, can someone tell me what the problem is?

#include <iostream>
#include <fstream>

#include <vector>

#include "TClass.h"

using namespace std;

int main(int argc,char **argv)
{
TClass::npts = 2;

vector<TClass> vec;

vec.resize(10);
int len=vec.size();

for(int i=0;i<len;i++)
{
for(int j=0;j<TClass::npts;j++)
{
vec.a[j]=j;
vec.b[j]=j+1;
cerr <<i<<" "<< vec.a[j]<< " " <<vec.b[j]<< endl;
}
}

return 0;
}

// TClass.h

class TClass
{
public:

static int npts;
int *a;
int *b;

public:

TClass();
~TClass();

};

// TClass.cpp

#include "TClass.h"

int TClass::npts;

TClass::TClass()
{
a=new int[npts];
b=new int[npts];
}

TClass::~TClass()
{
if(a) delete [] a;
if(b) delete [] b;
}
 
G

Guest

luigi,

try dereferencing TClass::a and TClass::b in the vectors when you set the
member variables

int* a;
a = some memory location
*a = (dereferencing) i.e. the contents of that memory location

vec.a[j]=j or in basic form vec.a[j]= 0 (first time through) is saying
that a = 0 and when you try and delete memory you dont own...KABOOM
it would be better to say *(vec.a[j]) = 0 or j giving you modification of
the contents of the memory location

Hope this helps....

Kevin
 
A

Attila Feher

luigi said:
The following code causes crash, can someone tell me what the problem
is? [SNIP]
#include "TClass.h"

int TClass::npts;

TClass::TClass()
{
a=new int[npts];
b=new int[npts];
}

TClass::~TClass()
{
if(a) delete [] a;
if(b) delete [] b;
}

You will need to define a copy constructor and an assignment operator for
TClass. Look up The Rule of Three.

WARNING! Untested example code!
WARNING! Code is not exception safe!

// TClass.h

class TClass {
private:
// Make these private

static int npts;

// You will need to know the
// size used here to be able
// to copy
int myNpts;
int *a;
int *b;

public:

void setNpts( int newNpts) {
npts = newNpts;
}
TClass();
TClass(TClass const &);
TClass const &operator=(TClass const &);
~TClass();

};


// TClass.cpp

#include "TClass.h"

int TClass::npts;

TClass::TClass() {
myNpts = npts;
a=new int[npts];
b=new int[npts];
}

TClass::TClass( TClass const &o) {
myNpts = npts;
a=new int[o.myNpts];
b=new int[o.myNpts];
// Copy them using a loop
// or memcpy or std::copy
}

TClass const &
TClass::eek:perator =( TClass const &o) {
// Don't try to copy self
if (this == &o) return;

if (myNpts != o.myNpts) {
delete delete [] a;
delete delete [] b;
a=new int[o.myNpts];
b=new int[o.myNpts];
}
// Copy them using a loop
// or memcpy or std::copy
}

TClass::~TClass() {
// if(a) delete [] a;
// No need for the if,
// you can delete a 0
// pointer
delete [] a;
delete [] b;
}

// Do not forget to define npts
int TClass::npts = 2;
// 2 is just an arbitrary default
 
H

Howard

luigi,

try dereferencing TClass::a and TClass::b in the vectors when you set the
member variables

int* a;
a = some memory location
*a = (dereferencing) i.e. the contents of that memory location

vec.a[j]=j or in basic form vec.a[j]= 0 (first time through) is saying
that a = 0 and when you try and delete memory you dont own...KABOOM
it would be better to say *(vec.a[j]) = 0 or j giving you modification of
the contents of the memory location

Hope this helps....

Kevin


Kevin,
[Please post your answers after the text you're referring to (or
interspersed with it at least).]

Your answer is not correct. The OP allocated two arrays of int, not two
arrays of pointers. Your method will try to dereference the int at
vec.a[j], but that's not allowed, since they're not pointers. The line
"a = new int[npts]" allocates an array of ints of size npts, and the
notation a[j] refers to the int at index j in that array. Also, setting
vec..a[j] = 0 will set a[j] to 0, not a. The pointer 'a 'points to
memory somewhere else, where the int's are actually stored. The int's are
*not* stored at the address of 'a', but at the address 'a' *points to*.

The OP's problem has to do with a lack of a proper copy-constructor, I
believe. (See Attila's response.)

-Howard
 
L

luigi

Thanks! The problem is fixed with the copy constructor. I will take
the rules more seriously from now on :->).

The resize(10) command calls default constructor once, then the copy
constructor 10 times, then destructor once. Very strange.
 
R

Ron Natalie

luigi said:
Thanks! The problem is fixed with the copy constructor. I will take
the rules more seriously from now on :->).

The resize(10) command calls default constructor once, then the copy
constructor 10 times, then destructor once. Very strange.

Not strange at all. The declaration of resize is:

resize(size_type sz, T c = T());

The second argument is an element that is used to initialize (by copy
construction in your observations) the newly created elements in the
array. Vector does not require that the contained type be default
constructable. In that case, you must provide a prototype object
for it to copy over these elements.

class C {
public:
int C(int); // no default constructor
};

vector<C> v;
v.resize(10, C(1));
 

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,744
Messages
2,569,482
Members
44,901
Latest member
Noble71S45

Latest Threads

Top