Почему оба указателя имеют одинаковый адрес памяти? - PullRequest
0 голосов
/ 27 января 2019
#include <iostream>

using namespace std;

int main()
{
    char* MainBlock = new char[100];

    char* SubBlock1 = new (MainBlock) char[20];

    char* SubBlock2 = new (MainBlock) char [20];

    cout  << static_cast<void*>(SubBlock1) << " " << static_cast<void*>(SubBlock2);


}

Почему оба указателя в приведенном выше коде имеют одинаковый адрес?Я ожидал, что SubBlock2 будет 20 байтов после SubBlock 1.

Означает ли это, что я могу выделить бесконечное количество указателей с новым размещением, даже если у меня только 100 байтов?

Как я могу гарантировать, чтоSubBlock6 будет nullptr или выходит за пределы, используя новое размещение?

Ответы [ 3 ]

0 голосов
/ 27 января 2019

Почему оба указателя в приведенном выше коде имеют одинаковый адрес?

Placement new принимает точный адрес, по которому он будет инициализировать создаваемый объект.Вы передаете тот же адрес, вы получаете тот же адрес.

Означает ли это, что я могу выделить бесконечное количество указателей с новым размещением, даже если у меня есть только 100 байтов?

Нет.Каждое размещение нового повторно использует хранилище.Конечно, вы можете многократно использовать хранилище бесконечно много раз, но вам будет выделено не более 100 одинаковых символов.

Как я могу гарантировать, что SubBlock6 будет иметь нулевой или нулевой предел при использовании нового размещения?

Нет способа.Начало работы - you , чтобы обеспечить действительное хранилище для размещения новых объектов для создания.Если вы этого не сделаете, поведение не определено.

И, наконец, вам не нужно возиться с размещением нового.

char *SubBlock1 = MainBlock;
char *SubBlock2 = MainBlock + 20;

Разделение буфера просто отлично.Только убедитесь, что delete[] только значение указателя, хранящееся в MainBlock.

0 голосов
/ 27 января 2019

Каждое new выражение , чтобы получить адрес, по которому строится объект, вызывает соответствующую функцию выделения .Как только выделение выполнено и адрес возвращен из функции выделения, он пытается построить объект точно по указанному адресу.

Учитывая char* SubBlock1 = new (MainBlock) char[20];, он вызывает следующую функцию выделения:

void* operator new[]( std::size_t count, void* ptr );

Вызывается стандартным массивом для размещения нового выражения.Реализация стандартной библиотеки не выполняет никаких действий и возвращает ptr без изменений.

Как сказано в документации выше, вызов этой функции распределения ничего не делает и возвращает адрес, который вы передали без изменений.Итак, это новое выражение создает 20 char точно в MainBlock.Вот почему вы получаете один и тот же адрес для SubBlock1 и SubBlock2.


Означает ли это, что я могу выделять бесконечное количество указателей с новым размещением, даже если у меня есть только 100байт?

Нет.Обратите внимание, что распределение и строительство - это две разные вещи.В вашем примере вы выделяете памяти только один раз и многократно строите объекты на ней.Таким образом, расположение объектов, построенных на выделенной памяти, зависит от вас.

0 голосов
/ 27 января 2019

Аргумент (MainBlock) является аргументом размещение .На самом деле вы явно указываете программе выделять SubBlock1 и SubBlock2 по адресу MainBlock.

...