0

I want to achieve the following behaviour:

  1. The class DataSequence has a pointer that points to an array in the main function.
  2. print the array when an object in initialised of the class DataSequence
  3. create a deep-copy of the same object (via a copy constructor) and print it when the object is formed.

The code I have written is as follows:

#include<bits/stdc++.h>
using namespace std;

class DataSequence{
float *ptr;
int _size;

public:
    DataSequence(float input[] , int size){
        _size = size;
        ptr = new float; ptr = input;
        //print the array
        cout << "Main constructor" << endl;
        for(int i=0 ; i<_size; ++i){
            cout << *(ptr+i) << " ";
            // ++ptr;
        }
    }

    //copy constructor
    DataSequence(DataSequence &d){
        _size = d._size;
        ptr = new float; *ptr = *(d.ptr);
        //print the array
        cout << "copy constrructor" << endl;
        for(int i=0 ; i<_size ; ++i){
            cout << *(ptr+i) <<" ";
            // ++ptr;
        }
    }
 };


int32_t main(){
int size=4;
float input[size];
int bins;
input[0] = 3.4;
input[1] = 1.3;
input[2] = 2.51;
input[3] = 3.24;   

DataSequence d(input , size);
cout << endl;
DataSequence d1 = d;

return 0;
}

The output is as follows

Main constructor
3.4 1.3 2.51 3.24
copy constrructor
3.4 2.42451e-038 -2.61739e-019 3.20687e-041

I am unable to figure out why I am getting garbage from the copy constructor, can someone help.

mike dirnt
  • 13
  • 2
  • 1
    When exactly is the "deep copying" supposed to be occurring in this code? – Nathan Pierson Oct 08 '20 at 16:30
  • `*ptr = *(d.ptr);` does not do a deep copy of the array. It just copies the first element. `ptr = input;` does not do a deep copy either it does a shallow copy and causes a memory leak of the single float you allocated in `ptr = new float;` right before this line. – drescherjm Oct 08 '20 at 16:37
  • This line: "ptr = new float; " allocates a single float, and the following "ptr = input;" overwrites ptr, a memory leak. Please review pointers. – 2785528 Oct 08 '20 at 16:41
  • Also, boilerplate warnings that `#include ` is a very dangerous habit (see https://stackoverflow.com/questions/31816095/why-should-i-not-include-bits-stdc-h ) and you're using a non-standard compiler extension when you write `float input[size];` and what you probably actually want is `float* input = new float[size];`. – Nathan Pierson Oct 08 '20 at 16:47
  • Also a copy constructor should properly have the signature `DataSequence(const DataSequence &d)` – Nathan Pierson Oct 08 '20 at 16:51

1 Answers1

4

This statement:

ptr = new float;

only allocates a single float. That means in this loop:

for(int i=0 ; i<_size; ++i){
    cout << *(ptr+i)

as soon as i is greater than 0, you dereference invalid memory, which is undefined behavior. This results in a program that can do anything, including producing the "garbage" output you see.

If you want to allocate an array, you need to do:

ptr = new float[_size];

and to delete it, you need to do:

delete [] ptr;

Note that even if you allocate memory correctly as shown above, you are not actually copying the data from the argument. Just setting pointers would do a shallow copy which is not what you want.

You can do a deep copy like this:

std::copy(d.ptr, d.ptr + _size, ptr);
cigien
  • 57,834
  • 11
  • 73
  • 112
  • Although `std::vector` is probably the best option. – Eljay Oct 08 '20 at 16:35
  • @Eljay Always :) But OP explicitly says they want to manage memory via a pointer. – cigien Oct 08 '20 at 16:35
  • @cigien I understand your logic (somehow I missed this earlier), however I am still getting garbage values after allocating the said memory of an array inside both the constructor and the copy constructor, now this is really intruiging – mike dirnt Oct 08 '20 at 16:45
  • @drescherjm could you please tell me the reason for your observation? I am sure that I have copied the said pointer in question, so how is it not a deep copy? – mike dirnt Oct 08 '20 at 16:46
  • In a deep copy you need to copy the elements not the pointer. Copying the pointer is a shallow copy. I explained both of these in my comment to the question. – drescherjm Oct 08 '20 at 16:47
  • 1
    @mikedirnt I've edited the answer to describe the issue, and the fix. – cigien Oct 08 '20 at 16:47