home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #30 / NN_1992_30.iso / spool / comp / lang / cplus / 18187 < prev    next >
Encoding:
Text File  |  1992-12-21  |  4.2 KB  |  176 lines

  1. Path: sparky!uunet!zaphod.mps.ohio-state.edu!swrinde!elroy.jpl.nasa.gov!ames!olivea!spool.mu.edu!umn.edu!myria.cs.umn.edu!hansen
  2. From: hansen@myria.cs.umn.edu (David Hansen)
  3. Newsgroups: comp.lang.c++
  4. Subject: Re: Can't I initialize a dynamically allocated object in its constructor?
  5. Message-ID: <1992Dec18.161017.17058@news2.cis.umn.edu>
  6. Date: 18 Dec 92 16:10:17 GMT
  7. References: <1992Dec17.205113.1180@IRO.UMontreal.CA>
  8. Sender: news@news2.cis.umn.edu (Usenet News Administration)
  9. Organization: University of Minnesota
  10. Lines: 163
  11. Nntp-Posting-Host: myria.cs.umn.edu
  12.  
  13. In article <1992Dec17.205113.1180@IRO.UMontreal.CA>, laviers@IRO.UMontreal.CA (Cocotte Minute) writes:
  14. |> Hello,
  15. |> 
  16. |> I have the following problem.
  17. |> 
  18. |>  I have created an class: Vector(k), it's
  19. |> a vector of k dimension (of doubles). After a whole week of debugging, 
  20. |> I have come to the conclusion that you must not set the values of the elements
  21. |>  of a class that are dynamically allocated (new) in the constructor.
  22. |> 
  23. [..]
  24. |> in this example: v1=[1,1,1],v2=[2,2,2],v3=[3,3,3]
  25. |> 
  26. |> without initialization 
  27. |>   (comment the line "for(int i=0;i<array_size;i++)item[i]=-1.0;")
  28. |> 
  29. |> v4=[6,6,6]; /* great! */
  30.  
  31. No, just lucky  :)
  32.  
  33. [..]
  34.  
  35. |> 
  36. |> Could this imply that the program gave the temporary (stack?) vector the
  37. |> value v1+v2 _before_ finishing to allocate (construct) it's space?
  38.  
  39. The problem is it doesn't get the value of v1+v2 _at_all_.
  40.  
  41. Because you do not define the copy constructor, the compiler does so for 
  42. you.  However, the compiler's copy ctor doesn't make a new item array, it
  43. just copies the address of the local temporary constructed in operator+
  44. When retVect in operator+ leaves scope, the destructor is called and 
  45. the memory pointed to by item is freed.  So the new temporary "item" is
  46. a dangling pointer.  Furthermore, when _that_ vector is destructed, "item"
  47. is _freed_again_.  Can you say "corrupted heap?"
  48.  
  49. Oh yeah, your destructor for vector is wrong.  You need to use the "delete []"
  50. form.  This, then, means you need to modify your default constructor to 
  51. use "item = new double[1];" so that vectors created with this constructor
  52. will be properly deleted.
  53.  
  54. The corrected code appears below.  Enjoy!
  55.  
  56.                     -=Dave
  57.  
  58. #include <stdio.h> 
  59. #include <stdlib.h>    // exit
  60.  
  61. //-------------------------------------------------------------------
  62. // Vector: vector of double
  63. //-------------------------------------------------------------------
  64.  
  65. class Vector{
  66.  
  67. double     *item ;
  68. int     size ;
  69.  
  70.     
  71. public :
  72.         
  73. // constructors 
  74. Vector() { item = new double[1] ; size = 1 ;}    // NOTE: use array form
  75. Vector(int array_size);
  76. Vector(const Vector & v);    // NOTE: new copy constructor
  77.  
  78. // destructors 
  79. ~Vector() { delete [] item ; }    // NOTE: use array form
  80.  
  81. // methods 
  82. int getsize() { return size ; }
  83.  
  84. void print(char *message);
  85.  
  86.  
  87. // operators 
  88. Vector operator+ (Vector& b);
  89. Vector& operator= (Vector& a);
  90. double& operator[] (int i);
  91. };
  92.  
  93.  
  94. // constructors
  95.  
  96. Vector::Vector(int array_size) { 
  97.    item = new double[array_size] ; 
  98.    size = array_size ;
  99.    printf("constructing\n");
  100.    for(int i=0;i<array_size;i++)item[i]=-1.0;
  101. }
  102.  
  103. // Definition of new copy constructor
  104. Vector::Vector(const Vector& v) {
  105.    int i;
  106.    size = v.size;
  107.    item = new double[size];
  108.    for (i=0; i<size; i++)
  109.       item[i] = v.item[i];
  110. }
  111.  
  112.  
  113. Vector Vector::operator+ (Vector& a){
  114.    if (getsize() != a.getsize()){
  115.       printf("operator '+':Vectors are not of the same size.\n");
  116.       exit(0);
  117.    }
  118.    Vector retVect(getsize()) ;
  119.    for (int i = 0 ; i < a.getsize() ; i++){
  120.       retVect.item[i] = item[i] + a.item[i] ;
  121.    }
  122.    return retVect ;
  123. }
  124.  
  125.  
  126.  
  127. Vector& Vector::operator= (Vector& a){
  128.    if (getsize() != a.getsize()){
  129.       printf("operator '=':Vectors are not of the same size.\n");
  130.       exit(0);
  131.    }
  132.    for (int i = 0 ; i < a.getsize() ; i++){
  133.       item[i] = a.item[i] ;
  134.    }
  135.    return *this ;
  136. }
  137.  
  138.  
  139. double& Vector::operator[](int i){
  140.    return item[i] ;
  141. }
  142.  
  143.  
  144. void  Vector::print(char *message) { 
  145.    printf("%s\n",message);
  146.    for (int i = 0 ; i < size ; i++){
  147.       printf("       [%d]=%lf\n", i, item[i]);
  148.    }
  149. }
  150.  
  151.  
  152.  
  153. main(){
  154.  
  155. Vector v1(3),v2(3),v3(3),v4(3);
  156.  
  157.  
  158.  
  159. v1[0]=1.0;
  160. v1[1]=1.0;
  161. v1[2]=1.0;
  162.  
  163. v2[0]=2.0;
  164. v2[1]=2.0;
  165. v2[2]=2.0;
  166.  
  167. v3[0]=3.0;
  168. v3[1]=3.0;
  169. v3[2]=3.0;
  170.  
  171. v4=v1+v2+v3;
  172.  
  173. v4.print("v4");
  174.  
  175. }
  176.