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

Malloc vs new - C++

Восстановить пароль Регистрация
 
 
Рейтинг: Рейтинг темы: голосов - 9, средняя оценка - 4.89
VoltDeMar
 Аватар для VoltDeMar
16 / 16 / 0
Регистрация: 05.06.2012
Сообщений: 1,015
08.07.2015, 14:54     Malloc vs new #1
Здравствуйте.

Вникаю в ручное управление памятью. Абзац из книги "C++ для профессионалов" не совпадает с моим представлением использования объектов. Тут написано:

C++
1
2
Foo* myFoo = {Foo*}malloc(sizeof(Foo));
Foo* myOtherFoo = new Foo();
После выполнения этих строк кода как переменная myFoo, так и переменная myOtherFoo будут указывать на области памяти в "куче", которые имею достаточный размер для хранения объекта Foo. К членам данных и методам объекта Foo можно получить доступ с помощью обоих указателей. Различие между ними состоит в том, что объект Foo, адресуемый указателем myFoo, не является, по сути, объектом, поскольку он не был построен.

Из других источников прочел что malloc не вызывает конструктор.

Но как это удается получить доступ к членам данных и методам объекта которого не существует. И образуется в памяти после выполнения malloc ?

Или это значит что после выделения памяти при помощи malloc нужно вручную вызывать конструктор?
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
08.07.2015, 14:54     Malloc vs new
Посмотрите здесь:

calloc vs malloc C++
malloc, realloc C++
malloc в С++ C++
malloc() C++
C++ malloc vs new
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
DrOffset
6421 / 3795 / 878
Регистрация: 30.01.2014
Сообщений: 6,584
08.07.2015, 23:54     Malloc vs new #21
IGPIGP, я не очень понял твой абзац. Но я скажу так: вызов функции - это бесспорно выражение, тут ты прав. Но не всякое выражение - это функция. Вот в данном случае есть выражение new (в стандарте new-expression) и есть функция аллокации (allocation function), которая называется operator new (оператор new). Выражение new приводит к вызову функции аллокации. Само по себе выражение new - это не функция. Это синтаксическая конструкция языка, которая отвечает за:
1) вызов соответствующей заданному типу функции аллокации, либо глобальной функции аллокации (operator new).
2) вызов соответствующего заданному типу конструктора, либо за проведение default-инициализации для типов, у которых конструктора нет.
Все это не является каким-то секретом или откровением и прямым текстом написано в стандарте языка.
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Croessmah
Модератор
Эксперт С++
 Аватар для Croessmah
11811 / 6790 / 767
Регистрация: 27.09.2012
Сообщений: 16,840
Записей в блоге: 2
Завершенные тесты: 1
08.07.2015, 23:57     Malloc vs new #22
Цитата Сообщение от DrOffset Посмотреть сообщение
Это синтаксическая конструкция языка, которая отвечает за
и как раз её перегрузить нельзя

Что касается placement-new, о это всего лишь вызов другой функции operator new, например такой:

C++
1
2
3
4
void* operator new (std::size_t size, void* ptr) noexcept
{
   return ptr ;
}
В дополнение:
Цитата Сообщение от Croessmah Посмотреть сообщение
например такой
//... code
то есть operator new при placement new просто возвращает переданный указатель, а не выделяет память.
new-expression же "берет" этот указатель и строит объект по адресу.
То есть new-expression одинаково работает как в placement new, так и "не в placement new"
DrOffset
6421 / 3795 / 878
Регистрация: 30.01.2014
Сообщений: 6,584
09.07.2015, 00:04     Malloc vs new #23
Цитата Сообщение от Croessmah Посмотреть сообщение
и как раз её перегрузить нельзя
Разумеется. Перегружать в С++ можно только функции (операторные или нет - не важно).
___
Товарищам, которые сейчас захотят вдуплить макрос, который переопределяет new, - сразу скажу, вы не правы. Ибо препроцессор не имеет никакого отношения к языку С++.
IGPIGP
Комп_Оратор)
 Аватар для IGPIGP
6160 / 2889 / 282
Регистрация: 04.12.2011
Сообщений: 7,688
Записей в блоге: 3
09.07.2015, 00:11     Malloc vs new #24
Цитата Сообщение от DrOffset Посмотреть сообщение
Но не всякое выражение - это функция.
Кто говорил о всяком? new как операторная функция является частным случаем выражения. Всегда. Поэтому если в стандарте в одном месте она называется операторной функцией, а в другом месте выражением для стилистического разнообразия, то это возможно (хотя и путает). Но если это делается для противопоставления, то это не лучший стандарт. Моё мнение. Стандартов в жизни видел немало. Хороших гораздо меньше, чем просто стандартов.
Функция встроена в язык и синтаксически выполнена в виде оператора. Параметры передаются через пробел в том числе. Конструктор - параметр. Есть параметры передаваемые и в скобках... Ну и что? Так придумал автор и это удобно. Думаю, говоря об одном и том же мы теряем нить. Я выступил по поводу того что "new на самом деле не всегда запускает конструктор" сказав, что его можно и память научить не выделять. Объявить указатель на void и вернуть неинициализированный. Такая перегрузка скомпилируется. Это как оператор + перегрузить, чтобы он пел Соловья Алябьева. Поэтому я нахожу фразу:
Цитата Сообщение от Evg Посмотреть сообщение
Просто new делает сразу две вещи - выделяет память (по сути malloc) и запускает конструктор.
вполне уместной. А уточнение что new может и не вызывать конструктор не логично. Если захотеть, то есть немного того что нельзя было бы заставить не вызывать или наоборот вызывать что угодно. Особенно если речь идёт о перегрузке.
Croessmah
Модератор
Эксперт С++
 Аватар для Croessmah
11811 / 6790 / 767
Регистрация: 27.09.2012
Сообщений: 16,840
Записей в блоге: 2
Завершенные тесты: 1
09.07.2015, 00:18     Malloc vs new #25
Цитата Сообщение от IGPIGP Посмотреть сообщение
Всегда. Поэтому если в стандарте в одном месте она называется операторной функцией, а в другом месте выражением для стилистического разнообразия
НЕТ! Это сделано для различия именно оператора new и new-выражения:
C++
1
2
int * x = new int ; //<-- new-expression
int * y = (int*)operator new ( sizeof(int) ) ; // <-- operator new
при этом new-expression вызывает operator new и конструирует объект в выделенной памяти.
operator new - просто выделяет сырую память, аля-malloc
DrOffset
6421 / 3795 / 878
Регистрация: 30.01.2014
Сообщений: 6,584
09.07.2015, 00:21     Malloc vs new #26
Цитата Сообщение от IGPIGP Посмотреть сообщение
Всегда. Поэтому если в стандарте в одном месте она называется операторной функцией, а в другом месте выражением для стилистического разнообразия, то это возможно (хотя и путает). Но если это делается для противопоставления, то это не лучший стандарт. Моё мнение.
О противопоставлении, вероятно, написано в статье (честно говоря я не ходил по ссылке). В стандарте никакого противопоставления нет. Одно включает другое. Вот в чем суть.
Но. Есть устоявшаяся терминология, которая диктуется официальным документом. Мы просто следуем ей и все.
Если мы будем называть функцию выделения памяти - operator new - выражением new, мы пойдем в разрез с этой терминологией и запутаем собеседника, который с этой терминологией знаком.
Цитата Сообщение от IGPIGP Посмотреть сообщение
Такая перегрузка скомпилируется
Здесь все-таки аналогия с оператором+ не совсем уместна. На функции аллокации накладываются целый свод требований
Кликните здесь для просмотра всего текста
1 An allocation function shall be a class member function or a global function; a program is ill-formed if an
allocation function is declared in a namespace scope other than global scope or declared static in global
scope. The return type shall be void*. The first parameter shall have type std::size_t (18.2). The first
parameter shall not have an associated default argument (8.3.6). The value of the first parameter shall be
interpreted as the requested size of the allocation. An allocation function can be a function template. Such
a template shall declare its return type and first parameter as specified above (that is, template parameter
types shall not be used in the return type and first parameter type). Template allocation functions shall
have two or more parameters.
2 The allocation function attempts to allocate the requested amount of storage. If it is successful, it shall
return the address of the start of a block of storage whose length in bytes shall be at least as large as
the requested size. There are no constraints on the contents of the allocated storage on return from the
allocation function. The order, contiguity, and initial value of storage allocated by successive calls to an
allocation function are unspecified. The pointer returned shall be suitably aligned so that it can be converted
to a pointer of any complete object type with a fundamental alignment requirement (3.11) and then used
to access the object or array in the storage allocated (until the storage is explicitly deallocated by a call
to a corresponding deallocation function). Even if the size of the space requested is zero, the request can
fail. If the request succeeds, the value returned shall be a non-null pointer value (4.10) p0 different from
any previously returned value p1, unless that value p1 was subsequently passed to an operator delete.
Furthermore, for the library allocation functions in 18.6.1.1 and 18.6.1.2, p0 shall point to a block of storage
disjoint from the storage for any other object accessible to the caller. The effect of indirecting through a
pointer returned as a request for zero size is undefined.36
3 An allocation function that fails to allocate storage can invoke the currently installed
new-handler function (18.6.2.3), if any. [ Note: A program-supplied allocation function can obtain the address of the currently
installed new_handler using the std::get_new_handler function (18.6.2.4). — end note ] If an allocation
function that has a non-throwing exception specification (15.4) fails to allocate storage, it shall return a null
pointer. Any other allocation function that fails to allocate storage shall indicate failure only by throwing
an exception (15.1) of a type that would match a handler (15.3) of type std::bad_alloc (18.6.2.1).
4 A global allocation function is only called as the result of a new expression (5.3.4), or called directly using the
function call syntax (5.2.2), or called indirectly through calls to the functions in the C++ standard library.
[ Note: In particular, a global allocation function is not called to allocate storage for objects with static
storage duration (3.7.1), for objects or references with thread storage duration (3.7.2), for objects of type
std::type_info (5.2.8), or for an exception object (15.1). — end note ]

, которым они должны следовать, чтобы программа оставалась well-formed. Для operator+ таких требований нет. Говорить о корректности программы, опираясь лишь на ее компилируемость, я считаю, не совсем верно.
Croessmah
Модератор
Эксперт С++
 Аватар для Croessmah
11811 / 6790 / 767
Регистрация: 27.09.2012
Сообщений: 16,840
Записей в блоге: 2
Завершенные тесты: 1
09.07.2015, 00:27     Malloc vs new #27
Цитата Сообщение от DrOffset Посмотреть сообщение
Для operator+ таких требований нет.
ну так для него нет и plus-expression
IGPIGP
Комп_Оратор)
 Аватар для IGPIGP
6160 / 2889 / 282
Регистрация: 04.12.2011
Сообщений: 7,688
Записей в блоге: 3
09.07.2015, 00:29     Malloc vs new #28
Цитата Сообщение от Croessmah Посмотреть сообщение
НЕТ! Это сделано для различия именно оператора new и new-выражения:
Это сделали враги рода человеческого (имхо). Саша, я понимаю разницу в вызове new A и new A()
Я пишу о том, что противопоставлять expression vs operator function это идея от лукавого. Что касается передаваемого параметра, то я привык считать, что когда имя конструктора (класса) передано без скобок то это значит что запускать конструктор не нужно и new его не запускает. Ну и что? Для POD типов даже конструкция вроде int(12345) ничего не запускает. Тут много нюансов созданных для синтаксического единообразия, в частности.
DrOffset
6421 / 3795 / 878
Регистрация: 30.01.2014
Сообщений: 6,584
09.07.2015, 00:39     Malloc vs new #29
Цитата Сообщение от IGPIGP Посмотреть сообщение
когда имя конструктора (класса) передано без скобок то это значит что запускать конструктор не нужно и new его не запускает.
Запускает. Для класса (не POD) - запускает всегда. Для pod-типов запускается не конструктор, а default инициализация. Либо zero-инициализация. Что по сути своей выполняет функцию конструктора, хоть и формально конструктора нет.

Добавлено через 7 минут
Цитата Сообщение от Croessmah Посмотреть сообщение
plus-expression
Вообще по факту есть
additive-expression
. Мы же не пишем в коде:
C++
1
operator+(a, b);
мы пишем
C++
1
a + b;
как бы, в этом коде синтаксически нет вызова функции. Но тем не менее, она вызывается. Выражение a + b ее вызывает.

В этом плане тут все очень единообразно.
Croessmah
Модератор
Эксперт С++
 Аватар для Croessmah
11811 / 6790 / 767
Регистрация: 27.09.2012
Сообщений: 16,840
Записей в блоге: 2
Завершенные тесты: 1
09.07.2015, 00:54     Malloc vs new #30
Цитата Сообщение от IGPIGP Посмотреть сообщение
Саша, я понимаю разницу в вызове new A и new A()
Здесь разница не в запуске конструкторов, а в том, что operator new - функция, а new-expression - синтаксическая конструкция языка.
A new-expression obtains storage for the object by calling an allocation function (3.7.4.1)
вот allocation function это как раз operator new

Добавлено через 2 минуты
Цитата Сообщение от DrOffset Посмотреть сообщение
Вообще по факту есть
мда... хреновый пример я привел...

Добавлено через 11 минут
Чтобы уж совсем показать разницу, в выражениях, посмотрим на то, каким выражением что является:
new-expression - это unary expression "new"
вызов operator new - это postfix expression "function call"
IGPIGP
Комп_Оратор)
 Аватар для IGPIGP
6160 / 2889 / 282
Регистрация: 04.12.2011
Сообщений: 7,688
Записей в блоге: 3
09.07.2015, 01:10     Malloc vs new #31
Цитата Сообщение от IGPIGP Посмотреть сообщение
Что касается передаваемого параметра, то я привык считать, что когда имя конструктора (класса) передано без скобок то это значит что запускать конструктор не нужно и new его не запускает. Ну и что?
Цитата Сообщение от DrOffset Посмотреть сообщение
Запускает
По умолчанию. Тут я уже написал не то. Сдаюсь. Ночью надо спать.
Перечитывая вопрос TC не вижу как он связан с operator new для выделения сырой памяти. Человек спрашивает: Почему есть доступ к членам по указателю как на инициализированный, так и не инициализированный объект. И строго говоря будь там среди членов еще указатель на char скажем, такой доступ может как угодно закончиться. То есть имелось в виду тоже не строгое утверждение. Но смыл сказанного ясен.
Croessmah
09.07.2015, 01:11
  #32

Не по теме:

Цитата Сообщение от IGPIGP Посмотреть сообщение
Ночью надо спать.
батюшки! А это еще зачем?

DrOffset
09.07.2015, 01:17
  #33

Не по теме:

Цитата Сообщение от IGPIGP Посмотреть сообщение
Человек спрашивает: Почему есть доступ к членам по указателю как на инициализированный, так и не инициализированный объект. И строго говоря будь там среди членов еще указатель на char скажем, такой доступ может как угодно закончиться.
Да. И на это уже был дан ответ. Остальное почти оффтоп. Но, я думаю, мы сейчас уже прекратим

MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
09.07.2015, 08:23     Malloc vs new
Еще ссылки по теме:

new на malloc C++
C++ new vs malloc
new, malloc, C++

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

Или воспользуйтесь поиском по форуму:
IGPIGP
09.07.2015, 08:23     Malloc vs new
  #34

Не по теме:

Цитата Сообщение от DrOffset Посмотреть сообщение
Да. И на это уже был дан ответ. Остальное почти оффтоп. Но, я думаю, мы сейчас уже прекратим
Может я уже забыл всё. Помню что new это операторная функция (в стандарте - expression ) a operator new - функция. Вообще с операторами весело если смешивать лексически похожие вещи. Например + унари/бинари, и еще ++ префикс/постфикс и... ещё пара плюсов в названии. Запряжённых зарёю.

Yandex
Объявления
09.07.2015, 08:23     Malloc vs new
Ответ Создать тему
Опции темы

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