Есть вот такая программа:
#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;
}
Вывод который она выдает:
1
Object constructor!
2
3
Object destructor!
4
Copy constructor!
Information from stored object is lambo
Object destructor!
По ней у меня есть несколько вопросов?
1. Мы в памяти сохранили объект который получили по ссылке перед тем как она вышла из области видимости. При условии что этот объект получаю из памяти, можно ли так делать? Если нет то как это исправить. Только просьба не советовать stl и vector. Я именно хочу разобраться глубоко при работе с памятью.
2. Есть ли какой-то undefined behavior в ее использовании кроме копирования объекта Storage?
Заранее благодарен за ответы и если можете скинуть ссылки где можно прочитать про нечто подобное, а именно использование подобной схемы управления памятью буду очень признателен.