From: hansen@myria.cs.umn.edu (David Hansen)
Newsgroups: comp.lang.c++
Subject: Re: Can't I initialize a dynamically allocated object in its constructor?
Date: 18 Dec 92 16:10:17 GMT
Organization: University of Minnesota

In article <1992Dec17.205113.1180@IRO.UMontreal.CA>, laviers@IRO.UMontreal.CA (Cocotte Minute) writes:
|> Hello,
|> 
|> I have the following problem.
|> 
|>  I have created an class: Vector(k), it's
|> a vector of k dimension (of doubles). After a whole week of debugging, 
|> I have come to the conclusion that you must not set the values of the elements
|>  of a class that are dynamically allocated (new) in the constructor.
|> 
[..]
|> in this example: v1=[1,1,1],v2=[2,2,2],v3=[3,3,3]
|> 
|> without initialization 
|>   (comment the line "for(int i=0;i<array_size;i++)item[i]=-1.0;")
|> 
|> v4=[6,6,6]; /* great! */

No, just lucky  :)

[..]

|> 
|> Could this imply that the program gave the temporary (stack?) vector the
|> value v1+v2 _before_ finishing to allocate (construct) it's space?

The problem is it doesn't get the value of v1+v2 _at_all_.

Because you do not define the copy constructor, the compiler does so for 
you.  However, the compiler's copy ctor doesn't make a new item array, it
just copies the address of the local temporary constructed in operator+
When retVect in operator+ leaves scope, the destructor is called and 
the memory pointed to by item is freed.  So the new temporary "item" is
a dangling pointer.  Furthermore, when _that_ vector is destructed, "item"
is _freed_again_.  Can you say "corrupted heap?"

Oh yeah, your destructor for vector is wrong.  You need to use the "delete []"
form.  This, then, means you need to modify your default constructor to 
use "item = new double[1];" so that vectors created with this constructor
will be properly deleted.

The corrected code appears below.  Enjoy!

					-=Dave

#include <stdio.h> 
#include <stdlib.h>	// exit

//-------------------------------------------------------------------
// Vector: vector of double
//-------------------------------------------------------------------

class Vector{

double 	*item ;
int 	size ;

	
public :
		
// constructors 
Vector() { item = new double[1] ; size = 1 ;}	// NOTE: use array form
Vector(int array_size);
Vector(const Vector & v);	// NOTE: new copy constructor

// destructors 
~Vector() { delete [] item ; }	// NOTE: use array form

// methods 
int getsize() { return size ; }

void print(char *message);


// operators 
Vector operator+ (Vector& b);
Vector& operator= (Vector& a);
double& operator[] (int i);
};


// constructors

Vector::Vector(int array_size) { 
   item = new double[array_size] ; 
   size = array_size ;
   printf("constructing\n");
   for(int i=0;i<array_size;i++)item[i]=-1.0;
}

// Definition of new copy constructor
Vector::Vector(const Vector& v) {
   int i;
   size = v.size;
   item = new double[size];
   for (i=0; i<size; i++)
      item[i] = v.item[i];
}


Vector Vector::operator+ (Vector& a){
   if (getsize() != a.getsize()){
      printf("operator '+':Vectors are not of the same size.\n");
      exit(0);
   }
   Vector retVect(getsize()) ;
   for (int i = 0 ; i < a.getsize() ; i++){
      retVect.item[i] = item[i] + a.item[i] ;
   }
   return retVect ;
}



Vector& Vector::operator= (Vector& a){
   if (getsize() != a.getsize()){
      printf("operator '=':Vectors are not of the same size.\n");
      exit(0);
   }
   for (int i = 0 ; i < a.getsize() ; i++){
      item[i] = a.item[i] ;
   }
   return *this ;
}


double& Vector::operator[](int i){
   return item[i] ;
}


void  Vector::print(char *message) { 
   printf("%s\n",message);
   for (int i = 0 ; i < size ; i++){
      printf("       [%d]=%lf\n", i, item[i]);
   }
}



main(){

Vector v1(3),v2(3),v3(3),v4(3);



v1[0]=1.0;
v1[1]=1.0;
v1[2]=1.0;

v2[0]=2.0;
v2[1]=2.0;
v2[2]=2.0;

v3[0]=3.0;
v3[1]=3.0;
v3[2]=3.0;

v4=v1+v2+v3;

v4.print("v4");

}
Newsgroups: comp.lang.c++