Объединение двух блоков памяти в C ++? - PullRequest
0 голосов
/ 10 июня 2018

Я пытаюсь создать свой собственный распределитель памяти в C ++ для образовательных целей, и у меня есть такой код:

class IntObj
{
public:
    IntObj(): var_int(6) {}

void setVar(int var)
{
    var_int = var;
}

int getVar()
{
    return var_int;
}

virtual size_t getMemorySize()
{
    return sizeof(*this);
}
int a = 8;

~IntObj()
{}
private:
    int var_int;
};

И я застрял в том, как объединить неиспользуемые фрагменты памяти.Я пытаюсь проверить это так:

char *pz = new char[sizeof(IntObj) * 2]; //In MacOS, IntObj takes 16 bytes
char *pz2 = &pz[sizeof(IntObj)]; // Take address of 16-th cell
char *pz3 = new char[sizeof(IntObj) / 2]; //Array of 8 bytes

char **pzz = &pz2; 
pzz[sizeof(IntObj)] = pz3; // Set address of cell 16 to the pz3 array
new (&pzz) IntObj; //placement new

IntObj *ss = reinterpret_cast<IntObj *>(&pzz);
cout << ss->a;

Выход 8, как и ожидалось.Мои вопросы:

  • Почему вывод правильный?
  • Правильно ли подобный код?Если нет, есть ли другие способы реализации объединения двух блоков памяти?

ОБНОВЛЕНИЕ: Все методы работают правильно.например, это будет работать:

ss->setVar(54);
cout << ss->getVar();

Вывод 54.

ОБНОВЛЕНИЕ 2: Прежде всего, моя задача не состоит в том, чтобы запросить новый блок памяти из ОС для создания экземпляра объекта, новыдавать его из связанного списка свободных блоков (которые были выделены при запуске программы).Моя проблема в том, что у меня могут быть полиморфные объекты разных размеров, и я не знаю, как разделить блоки памяти или объединить (это то, что я понимаю, объединяя или объединяя куски) их (если выделение запрошено) эффективно.

1 Ответ

0 голосов
/ 10 июня 2018

Здесь присутствует ряд недоразумений

char *pz = new char[sizeof(IntObj) * 2];  // fine
char *pz2 = &pz[sizeof(IntObj)];          // fine
char *pz3 = new char[sizeof(IntObj) / 2]; // fine
char **pzz = &pz2;                        // fine
pzz[sizeof(IntObj)] = pz3;                // bad

pzz - это указатель, который указывает только на один char*, который является переменной pz2.Это означает, что любой доступ или модификация после pzz[0] является неопределенным поведением (очень плохо).Вы, вероятно, изменяете содержимое какой-то другой переменной.

new (&pzz) IntObj; // questionable

Это создает IntObj в пространстве переменной pzz, а не там, куда указывает pzz.Конструктор курса устанавливает a в 8, тем самым растоптывая содержимое pzz (больше не будет указывать на pz2).Я не уверен, является ли это само по себе неопределенным поведением (так как было бы место для целого IntObj), но с использованием это, безусловно, равно:

IntObj *ss = reinterpret_cast<IntObj *>(&pzz); // bad

Это нарушает правило строгого наложения имен.Хотя стандарт является щедрым для char* псевдонимов, он не допускает псевдонимы char** - IntObj*.Это демонстрирует более неопределенное поведение.

Если ваш вопрос сводится к тому, можете ли вы использовать два независимых и смежных блока памяти как один блок, то нет, вы не можете.

...