Форум программистов, компьютерный форум CyberForum.ru

Как работает динамическое выделение памяти под объект? - C++

Восстановить пароль Регистрация
 
mzarb
-211 / 7 / 1
Регистрация: 14.01.2013
Сообщений: 141
14.03.2013, 19:58     Как работает динамическое выделение памяти под объект? #1
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class A
{
public:
  A(int x){}
  ~A(){}
};
const int n = 50;
A* placementMemory = static_cast<A*>(operator new[] (n * sizeof(A)));
for (int i = 0; i < n; i++)
{
  new (placementMemory + i) A(rand());
}
for (int i = 0; i < n; i++)
{
  placementMemory[i].~A();
}
operator delete[] (placementMemory);
В 8 строчке вызвалась перегруженная глобальная функция "operator new[]", потом эта функция приняла аргументом размер для выделения памяти для 50 объектов размера "A" и вернула указатель на эту выделенную память, дальше static_cast привел этот указатель к типу "A" и присвоил значения(адрес на выделенную память, который содержался в указателе) указателя к указателю placementMemory.
Но вот не пойму, что происходить в 11 строчке. Какая будет использоваться перегруженная версия new и она там будет не одна? Я так же не понимаю такой пример : A *p = new A;. Сначала вызывается new и выделяется память и возвращается указатель на эту выделенную память, а потом запускается конструктор класса A(), но кто будет инициализировать этот конструктор на этой динамически выделенной памяти(указатель на которую вернула new), а не на стеке, ведь new вернула только указатель на выделенную память и не понятно каким образом конструктор должен на этой выделенной памяти инициализироваться?
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Vourhey
Почетный модератор
6468 / 2243 / 123
Регистрация: 29.07.2006
Сообщений: 12,635
14.03.2013, 20:06     Как работает динамическое выделение памяти под объект? #2
mzarb, конструктор никто не должен инициализировать. Это обычная функция. Ее код уже в памяти лежит. Еще до всяких вызовов new и т. д..

Добавлено через 2 минуты
Цитата Сообщение от mzarb Посмотреть сообщение
Но вот не пойму, что происходить в 11 строчке. Какая будет использоваться перегруженная версия new и она там будет не одна?
new с передачей адреса
mzarb
-211 / 7 / 1
Регистрация: 14.01.2013
Сообщений: 141
14.03.2013, 20:40  [ТС]     Как работает динамическое выделение памяти под объект? #3
Vourhey, я не так выразился. Я имел ввиду, если запустится конструктор, то он же инициализирует поля класса на стеке, а откуда он будет знать что нужно разместить не на стеке, а в куче? К примеру когда делал вывод сообщение по входу в функцию, то сначала входило в operator new, а потом в конструктор. Или же конструктор как-то попадет в какой-то перегруженный new и там уже как-то инициализируется в куче? Могли бы вы написать реализации нужных перегруженных new к коду в вопросе?
Vourhey
Почетный модератор
6468 / 2243 / 123
Регистрация: 29.07.2006
Сообщений: 12,635
14.03.2013, 23:34     Как работает динамическое выделение памяти под объект? #4
Цитата Сообщение от mzarb Посмотреть сообщение
то он же инициализирует поля класса на стеке, а откуда он будет знать что нужно разместить не на стеке, а в куче?
Конструктор не выделяет память и ничего нигде не размещает. Он работает с уже выделенной областью (в общем случае). На вход получит адрес данных объекта. В куче они лежат, или на стеке ему совершенно фиолетово.
Цитата Сообщение от mzarb Посмотреть сообщение
Могли бы вы написать реализации нужных перегруженных new к коду в вопросе?
Там и так все в порядке.
Цитата Сообщение от mzarb Посмотреть сообщение
К примеру когда делал вывод сообщение по входу в функцию, то сначала входило в operator new, а потом в конструктор. Или же конструктор как-то попадет в какой-то перегруженный new и там уже как-то инициализируется в куче?
Ниче не понял, что ты написал. new выделит память под объект и вызовет для него конструктор, которому передаст адрес выделенной памяти. Очередность "вхождения" у тебя правильная.
mzarb
-211 / 7 / 1
Регистрация: 14.01.2013
Сообщений: 141
15.03.2013, 00:47  [ТС]     Как работает динамическое выделение памяти под объект? #5
Vourhey, А каким образом он передает конструктору адрес выделенной памяти? Возможно глупый вопрос, но что-то я не могу этого представить. Могли бы вы поподробнее объяснить?
Vourhey
Почетный модератор
6468 / 2243 / 123
Регистрация: 29.07.2006
Сообщений: 12,635
15.03.2013, 01:10     Как работает динамическое выделение памяти под объект? #6
Цитата Сообщение от mzarb Посмотреть сообщение
А каким образом он передает конструктору адрес выделенной памяти?
Есть у тебя функция, которая параметром принимает указатель. Вот таким образом и передается. Как обычный вызов функции с передачей ей аргумента. И любые нестатические функции-члены работают аналогично. Просто для это выглядит, как объект.функция(); а в итоге, функция(адрес_объекта);
mzarb
-211 / 7 / 1
Регистрация: 14.01.2013
Сообщений: 141
15.03.2013, 02:32  [ТС]     Как работает динамическое выделение памяти под объект? #7
Vourhey, спасибо. Я почему-то думал, что new возвращает rvalue, так как нет возможности обратится к этой памяти или применить операцию взятия адреса, по крайней мере до присваивания указателю, по этому откинул версию "объект.функция()".
А new возвращает адрес выделенной памяти или все же указатель(без имени или с именем) на эту память?
И что будет делать конструктор, он инициализирует память нулями ?
И есть ли у этого объекта(адреса) такой же доступ к полям класса как и у обычных объектов, то есть можно ли будет в конструкторе писать адрес.поле и присваивать им аргументы если есть? То есть A или A() - это определения объекта без имени(но с адресом) типа A , а в примере "new (placementMemory + i) A(rand()" - это определение объекта без имени(с адресом , который вернет new) типа A и инициализация его значением "rand()" ? Если да, то почему адрес туда подставляется после типа?
И последний вопрос, static_cast преобразует к нужному типу, разбивая выделенный кусок на размер полей и располагая их последовательно в этом участке памяти?
Буду очень благодарен за ответ.
Vourhey
Почетный модератор
6468 / 2243 / 123
Регистрация: 29.07.2006
Сообщений: 12,635
15.03.2013, 12:34     Как работает динамическое выделение памяти под объект? #8
Цитата Сообщение от mzarb Посмотреть сообщение
Я почему-то думал, что new возвращает rvalue, так как нет возможности обратится к этой памяти или применить операцию взятия адреса, по крайней мере до присваивания указателю, по этому откинул версию "объект.функция()".
Не важно, что возвращает new. Представь, что внутри него, грубо, реализован такой элементарный механизм:
1. вызов системной функции для выделения памяти
2. вызов конструктора для выделенного блока памяти
3. возвращение адреса памяти тебе в программу.
все, ничего сложного выдумывать не надо. Никаких rvalue.
Цитата Сообщение от mzarb Посмотреть сообщение
А new возвращает адрес выделенной памяти или все же указатель(без имени или с именем) на эту память?
Значение указателя и есть адрес
Цитата Сообщение от mzarb Посмотреть сообщение
И что будет делать конструктор, он инициализирует память нулями ?
Кто инициализирует память нулями? Конструктору, опять же, не важно, что лежит в памяти в общем случае. Он знает смещения, ему этого достаточно.
Цитата Сообщение от mzarb Посмотреть сообщение
И есть ли у этого объекта(адреса) такой же доступ к полям класса как и у обычных объектов
Ниче не понял. У нас разве необычный объект? Правда доступа и поля класса - это только языковые понятия. После компиляции они исчезают. Как и сами объекты.
Цитата Сообщение от mzarb Посмотреть сообщение
то есть можно ли будет в конструкторе писать адрес.поле и присваивать им аргументы если есть?
Почитай про this. Считай, что вот "оно" и есть переданный твоим функциям-членам скрытый указатель.
Цитата Сообщение от mzarb Посмотреть сообщение
Если да, то почему адрес туда подставляется после типа?
Адрес не после типа, а после new в скобках.

Добавлено через 8 минут
Цитата Сообщение от mzarb Посмотреть сообщение
указатель(без имени или с именем)
Что значит "вернуть с именем"?
mzarb
-211 / 7 / 1
Регистрация: 14.01.2013
Сообщений: 141
15.03.2013, 21:48  [ТС]     Как работает динамическое выделение памяти под объект? #9
Цитата Сообщение от Vourhey Посмотреть сообщение
Значение указателя и есть адрес
Цитата Сообщение от Vourhey Посмотреть сообщение
Что значит "вернуть с именем"?
Я понимаю, что значение указателя - это адрес на то, куда он указывает и наверное это не принципиально важно, но когда new возвращает что-то, к примеру адрес содержащийся в значении возвращаемого указателя, то будет присвоение уже вне функции, где-то возле вызова и выглядеть это будет как : void* noname = p, где p это указатель, который вернула new, а void * noname то, что приняло его.То есть технически все же возвращается указатель без имени содержащий в своем значении адрес на выделенную память, который вернулся с new по указателю, который содержал его? Хотя опять же в данном случае это большой роли не играет, так как все ровно обратится к этому указателю не получится. То есть не важно что подставится в виде объекта, адрес, который вернул new или все же указатель без имени содержащий этот адрес? Откуда я это все взял? Вот ссылка
Цитата Сообщение от Vourhey Посмотреть сообщение
Кто инициализирует память нулями? Конструктору, опять же, не важно, что лежит в памяти в общем случае. Он знает смещения, ему этого достаточно.
А конструктор, который запустится без параметров или поумолчанию, он же будет инициализировать объект на выделенной памяти, но а что тогда подразумевается под инициализацией? Или если без параметров запускать, то инициализации нету, а есть только объявление, но в случае с классами объявление объектов и есть их инициализация даже если нету передачи аргументов в конструктор. Вообщем, код A a; создаст объект и запустит конструктор поумолчанию, а этот конструктор будет что-то делать, то есть какую-либо инициализацию?
Цитата Сообщение от Vourhey Посмотреть сообщение
Адрес не после типа, а после new в скобках.
Допустим есть код A *p = new A();. Так вот A() - это же не конструктор, то есть не вызов как обычной функции, а имеется ввиду создание объекта типа A и вызов конструктора без параметров, то есть имя этого объекта, которое будет стоять между "A" и "()", это адрес/указаnель, который вернет new. Так вот каким образом этот адрес/указатель подставится между "A" и "()"?
Kuzia domovenok
 Аватар для Kuzia domovenok
1882 / 1737 / 116
Регистрация: 25.03.2012
Сообщений: 5,907
Записей в блоге: 1
15.03.2013, 22:01     Как работает динамическое выделение памяти под объект? #10
Что за поток сознания? Чёрт не разберёт.
Лучше не умничай и не переусложняй проблему, а говори прямо, что тебя побудило это написать? Чувствую, что ты сам выдумал эту несуществующую проблему на пустом месте. Начитался каких-то ненужных статеек?
Короче, пиши код и пиши, что конкретно неясно.

Добавлено через 4 минуты
Цитата Сообщение от mzarb Посмотреть сообщение
Так вот каким образом этот адрес/указатель подставится между "A" и "()"?
а какая разница? С++ это самостоятельный язык, а не набор, например, макросов, превращающих вызовы new в вызовы конструкторов как сишных функций.
Vourhey
Почетный модератор
6468 / 2243 / 123
Регистрация: 29.07.2006
Сообщений: 12,635
15.03.2013, 22:25     Как работает динамическое выделение памяти под объект? #11
mzarb, ни черта не понял из того, что ты написал. Текста много, смысл - хрен разберешь. Че-то ты навыдумывал себе.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
15.03.2013, 23:30     Как работает динамическое выделение памяти под объект?
Еще ссылки по теме:

Динамическое выделение памяти под массив C++
Динамическое выделение памяти под двумерный массив C++
C++ Динамическое выделение памяти под массив

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
mzarb
-211 / 7 / 1
Регистрация: 14.01.2013
Сообщений: 141
15.03.2013, 23:30  [ТС]     Как работает динамическое выделение памяти под объект? #12
Kuzia domovenok, что за агрессия? Я описал по два раза то, что мне не понятно, если вы это не поняли или не захотели понимать, то я не могу вас заставить и я понимаю что тут мне никто не обязан чем-то. Так что можно просто пройти мимо и не нужно оставлять критики не направленную на что-то конкретное. А просто выражать свое негодования по тому, что я расписал подробно что именно мне не понятно - это смешно. Может я и не спец по объяснению того, что хочу, но если бы я задал вопрос в двух словах, то вряд ли бы вы что-то поняли или бы поняли не правильно и пришлось бы ещё и ещё задавать вопросы или я бы не понял и воспринял ложное определение. А по поводу кода, на примере которого будет дан ответ, то код был.

Не по теме:

Советую вам php использовать, там не нужно задумываться ни о чем.



Добавлено через 3 минуты
Vourhey, ладно, спасибо за помощь, остальное уже как-то сам переварю.
Yandex
Объявления
15.03.2013, 23:30     Как работает динамическое выделение памяти под объект?
Ответ Создать тему
Опции темы

Текущее время: 08:54. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru