lundi 29 octobre 2018

Why after deleting object which reference points to it continues to live?

I have such program:

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>

class no_object : public std::exception
{
    protected:
        std::string mMsg;
    public:
        no_object(const char* msg) : mMsg(msg) {}
        virtual ~no_object() noexcept override {}
        virtual const char* what() const noexcept override { return mMsg.c_str(); }
};

using namespace std;

class Object {
public:
    Object(const string info) : information(info) { cout << "Object constructor!" << endl; }
    ~Object() { cout << "Object destructor!" << endl; }
    Object(const Object& obj) { information = obj.information; cout << "Copy constructor!" << endl; }
    void setInformation() {  }
    string getInformation() const { return information; }
private:
    string information;
};

class Storage {
public:
    Storage(const size_t width) {
        objs = static_cast<Object*>(malloc(sizeof(Object) * width));

        if (objs == NULL)
            throw std::bad_alloc();

        lastPointer = objs + sizeof (Object) * (width - 1);
    }

    void storeObject(Object& obj, size_t index) {
        if (isIndexOutOfRange(index))
            throw std::out_of_range("Oops, index is out of range!");

        availableIndexes.push_back(index);
        objs[index] = obj;
    }

    Object& getObjectAtIndex(size_t index) const {
        if (isIndexOutOfRange(index))
            throw std::out_of_range("Oops, index is out of range!");

        auto it = find(availableIndexes.begin(), availableIndexes.end(), index);
        if (it == availableIndexes.end())
            throw no_object("Oops, the object for this index is not set!");

        return objs[index];
    }

    ~Storage() {
        free(objs);
    }
private:
    bool isIndexOutOfRange(size_t index) const noexcept {
        Object* indexPointer = objs + sizeof (Object) * index;

        if (indexPointer > lastPointer)
            return true;

        return false;
    }

    vector<size_t> availableIndexes;

    Object* objs;
    Object* lastPointer;
};

int main()
{
    Storage storage(3);
    {
        cout << "1" << endl;
        Object obj = Object("lambo");
        cout << "2" << endl;
        Object& objRef = obj;
        cout << "3" << endl;
        storage.storeObject(objRef, 2);
    }

    cout << "4" << endl;
    Object savedObject = storage.getObjectAtIndex(2);
    cout << "Information from stored object is " << savedObject.getInformation() << endl;

    return 0;
}

Interesting thing is that I have next output:

1
Object constructor!
2
3
Object destructor!
4
Copy constructor!
Information from stored object is lambo
Object destructor!

This program stores references to objects and then we can get them. As I know after object to which reference points to is deleted, the reference become unavailable and it points to garbage. But in my case copy constructor is called.

Maybe you could help me to understand it more deeply, because now I am confused. Thanks in advance, also if you could point me on other potential problems that will help me a lot too.

Aucun commentaire:

Enregistrer un commentaire