Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Inconsistent behaviour c++ classes in classes

Edit based on the comments and the answer:

class Array {

public:
    int size;
    int *elements;

    explicit Array(int maxSize) : size(0), elements(new int[maxSize]) {}

    Array(Array &old) : elements(static_cast<int *>(malloc(sizeof(int) * size))), size(old.size) {
        memcpy(elements, old.elements, sizeof(int) * size);
    }

    Array(Array &&old) noexcept : size(old.size), elements(old.elements) {
        old.elements = nullptr;
    }

    ~Array() {
        delete[] elements;
    }

    void add(int e) {
        elements[size++] = e;
    }
};
class Base {

public:
    Array a;

    explicit Base(Array &a) : a(std::move(a)) {}
};

int main() {

    Array a(5);
    a.add(1);
    std::cout << "Address: "<< a.elements << std::endl;
    std::cout << "First element: "<< a.elements[0] << std::endl;
    Array b = std::move(a);
    std::cout << "Address: "<< b.elements << std::endl;
    std::cout << "First element: "<< b.elements[0] << std::endl;
    Base c(b);
    std::cout << "Address: "<< c.a.elements << std::endl;
    std::cout << "First element: "<< c.a.elements[0] << std::endl;

    Base *d = static_cast<Base *>(malloc(sizeof(Base) * 2));
    Array e = std::move(c.a);
    std::cout << "Address: "<< e.elements << std::endl;
    std::cout << "First element: "<< e.elements[0] << std::endl;

    new (d) Base(e);
    std::cout << "Address: "<< d[0].a.elements << std::endl;
    std::cout << "First element: "<< d[0].a.elements[0] << std::endl;
}

I am trying to make some tailored structs and classes in c++, and I am having some issues in copy constructors of classes.

What I am trying to do is to create a class in which a pointer is copied within the copy constructor and replaced with nullpointer in the previous object. Everything is fine until I try to do it inside another class.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

In that case the first element of the array change value for no reason (I can explain).

Here is a mre:

class Array {

public:
    int *elements;
    int size;

    explicit Array(int maxSize) : size(0), elements(static_cast<int *>(malloc(sizeof(int) * maxSize))) {}

    Array(Array &old) : size(old.size), elements(old.elements) {
        old.elements = nullptr;
    }

    ~Array() {
        delete elements;
    }

    void add(int e) {
        elements[size++] = e;
    }
};
class Base {

public:
    Array a;

    explicit Base(Array &a) : a(a) {}
};
int main() {
    Array a(5);
    a.add(1);
    std::cout << "Address: "<< a.elements << std::endl;
    std::cout << "First element: "<< a.elements[0] << std::endl;
    Array b = a;
    std::cout << std::endl << "Old address: "<< a.elements << std::endl;
    std::cout << "Address: "<< b.elements << std::endl;
    std::cout << "First element: "<< b.elements[0] << std::endl;
    Base c(b);
    std::cout << std::endl << "Old address: "<< b.elements << std::endl;
    std::cout << "Address: "<< c.a.elements << std::endl;
    std::cout << "First element: "<< c.a.elements[0] << std::endl;
    Base *d = static_cast<Base *>(malloc(sizeof(Base) * 2));
    Array e = c.a;
    std::cout << std::endl << "Old address: "<< c.a.elements << std::endl;
    std::cout << "Address: "<< e.elements << std::endl;
    std::cout << "First element: "<< e.elements[0] << std::endl;
    d[0] = Base(e);
    std::cout << std::endl << "Old address: "<< c.a.elements << std::endl;
    std::cout << "Address: "<< d[0].a.elements << std::endl;
    std::cout << "First element: "<< d[0].a.elements[0] << std::endl;
}

Output:

Address: 0x560838558eb0
First element: 1

Old address: 0
Address: 0x560838558eb0
First element: 1

Old address: 0
Address: 0x560838558eb0
First element: 1

Old address: 0
Address: 0x560838558eb0
First element: 1

Old address: 0
Address: 0x560838558eb0
First element: 1619232088

Process finished with exit code 0

>Solution :

Your d object does not hold a valid array of Base objects. You merely allocated memory that may or may not be sufficient. But you never instantiated an object of type Base. So you cannot expect to use it.

If you need an old style array, just create it:

Base d[2] = {/*initialisation*/};

or use new if you need it on the free store. Usually, if you use malloc or its counterpart free in C++, you are likely doing something wrong.

Also, and not directly related, have a look at std::exchange.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading