Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.76/41: Рейтинг темы: голосов - 41, средняя оценка - 4.76
18 / 18 / 4
Регистрация: 05.06.2012
Сообщений: 1,020
1

Malloc vs new

08.07.2015, 14:54. Показов 7703. Ответов 33
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Здравствуйте.

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

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

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

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

Или это значит что после выделения памяти при помощи malloc нужно вручную вызывать конструктор?
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
08.07.2015, 14:54
Ответы с готовыми решениями:

В чем разница между malloc() и (char *)malloc()
Прошу помочь разобраться: не могу понять в чем разница междуs=malloc(sizeof(char)); иs=(char...

new vs malloc
Чем new безопаснее(или лучше?) malloc?

New и malloc
Если смотреть на выделение памяти для арифметических типов уступает ли функций new malloc'у в...

malloc в С++
Подскажите пожалуйста как в данной программе выделить динамическую память с помощью malloc для...

33
18844 / 9843 / 2408
Регистрация: 30.01.2014
Сообщений: 17,285
08.07.2015, 23:54 21
Author24 — интернет-сервис помощи студентам
IGPIGP, я не очень понял твой абзац. Но я скажу так: вызов функции - это бесспорно выражение, тут ты прав. Но не всякое выражение - это функция. Вот в данном случае есть выражение new (в стандарте new-expression) и есть функция аллокации (allocation function), которая называется operator new (оператор new). Выражение new приводит к вызову функции аллокации. Само по себе выражение new - это не функция. Это синтаксическая конструкция языка, которая отвечает за:
1) вызов соответствующей заданному типу функции аллокации, либо глобальной функции аллокации (operator new).
2) вызов соответствующего заданному типу конструктора, либо за проведение default-инициализации для типов, у которых конструктора нет.
Все это не является каким-то секретом или откровением и прямым текстом написано в стандарте языка.
0
Неэпический
17870 / 10635 / 2054
Регистрация: 27.09.2012
Сообщений: 26,737
Записей в блоге: 1
08.07.2015, 23:57 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"
0
18844 / 9843 / 2408
Регистрация: 30.01.2014
Сообщений: 17,285
09.07.2015, 00:04 23
Цитата Сообщение от Croessmah Посмотреть сообщение
и как раз её перегрузить нельзя
Разумеется. Перегружать в С++ можно только функции (операторные или нет - не важно).
___
Товарищам, которые сейчас захотят вдуплить макрос, который переопределяет new, - сразу скажу, вы не правы. Ибо препроцессор не имеет никакого отношения к языку С++.
0
Комп_Оратор)
Эксперт по математике/физике
8950 / 4704 / 629
Регистрация: 04.12.2011
Сообщений: 13,999
Записей в блоге: 16
09.07.2015, 00:11 24
Цитата Сообщение от DrOffset Посмотреть сообщение
Но не всякое выражение - это функция.
Кто говорил о всяком? new как операторная функция является частным случаем выражения. Всегда. Поэтому если в стандарте в одном месте она называется операторной функцией, а в другом месте выражением для стилистического разнообразия, то это возможно (хотя и путает). Но если это делается для противопоставления, то это не лучший стандарт. Моё мнение. Стандартов в жизни видел немало. Хороших гораздо меньше, чем просто стандартов.
Функция встроена в язык и синтаксически выполнена в виде оператора. Параметры передаются через пробел в том числе. Конструктор - параметр. Есть параметры передаваемые и в скобках... Ну и что? Так придумал автор и это удобно. Думаю, говоря об одном и том же мы теряем нить. Я выступил по поводу того что "new на самом деле не всегда запускает конструктор" сказав, что его можно и память научить не выделять. Объявить указатель на void и вернуть неинициализированный. Такая перегрузка скомпилируется. Это как оператор + перегрузить, чтобы он пел Соловья Алябьева. Поэтому я нахожу фразу:
Цитата Сообщение от Evg Посмотреть сообщение
Просто new делает сразу две вещи - выделяет память (по сути malloc) и запускает конструктор.
вполне уместной. А уточнение что new может и не вызывать конструктор не логично. Если захотеть, то есть немного того что нельзя было бы заставить не вызывать или наоборот вызывать что угодно. Особенно если речь идёт о перегрузке.
0
Неэпический
17870 / 10635 / 2054
Регистрация: 27.09.2012
Сообщений: 26,737
Записей в блоге: 1
09.07.2015, 00:18 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
0
18844 / 9843 / 2408
Регистрация: 30.01.2014
Сообщений: 17,285
09.07.2015, 00:21 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+ таких требований нет. Говорить о корректности программы, опираясь лишь на ее компилируемость, я считаю, не совсем верно.
0
Неэпический
17870 / 10635 / 2054
Регистрация: 27.09.2012
Сообщений: 26,737
Записей в блоге: 1
09.07.2015, 00:27 27
Цитата Сообщение от DrOffset Посмотреть сообщение
Для operator+ таких требований нет.
ну так для него нет и plus-expression
0
Комп_Оратор)
Эксперт по математике/физике
8950 / 4704 / 629
Регистрация: 04.12.2011
Сообщений: 13,999
Записей в блоге: 16
09.07.2015, 00:29 28
Цитата Сообщение от Croessmah Посмотреть сообщение
НЕТ! Это сделано для различия именно оператора new и new-выражения:
Это сделали враги рода человеческого (имхо). Саша, я понимаю разницу в вызове new A и new A()
Я пишу о том, что противопоставлять expression vs operator function это идея от лукавого. Что касается передаваемого параметра, то я привык считать, что когда имя конструктора (класса) передано без скобок то это значит что запускать конструктор не нужно и new его не запускает. Ну и что? Для POD типов даже конструкция вроде int(12345) ничего не запускает. Тут много нюансов созданных для синтаксического единообразия, в частности.
0
18844 / 9843 / 2408
Регистрация: 30.01.2014
Сообщений: 17,285
09.07.2015, 00:39 29
Цитата Сообщение от IGPIGP Посмотреть сообщение
когда имя конструктора (класса) передано без скобок то это значит что запускать конструктор не нужно и new его не запускает.
Запускает. Для класса (не POD) - запускает всегда. Для pod-типов запускается не конструктор, а default инициализация. Либо zero-инициализация. Что по сути своей выполняет функцию конструктора, хоть и формально конструктора нет.

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

В этом плане тут все очень единообразно.
1
Неэпический
17870 / 10635 / 2054
Регистрация: 27.09.2012
Сообщений: 26,737
Записей в блоге: 1
09.07.2015, 00:54 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"
0
Комп_Оратор)
Эксперт по математике/физике
8950 / 4704 / 629
Регистрация: 04.12.2011
Сообщений: 13,999
Записей в блоге: 16
09.07.2015, 01:10 31
Цитата Сообщение от IGPIGP Посмотреть сообщение
Что касается передаваемого параметра, то я привык считать, что когда имя конструктора (класса) передано без скобок то это значит что запускать конструктор не нужно и new его не запускает. Ну и что?
Цитата Сообщение от DrOffset Посмотреть сообщение
Запускает
По умолчанию. Тут я уже написал не то. Сдаюсь. Ночью надо спать.
Перечитывая вопрос TC не вижу как он связан с operator new для выделения сырой памяти. Человек спрашивает: Почему есть доступ к членам по указателю как на инициализированный, так и не инициализированный объект. И строго говоря будь там среди членов еще указатель на char скажем, такой доступ может как угодно закончиться. То есть имелось в виду тоже не строгое утверждение. Но смыл сказанного ясен.
0
Croessmah
09.07.2015, 01:11
  #32

Не по теме:

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

0
DrOffset
09.07.2015, 01:17
  #33

Не по теме:

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

0
IGPIGP
09.07.2015, 08:23     Malloc vs new
  #34

Не по теме:

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

0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
09.07.2015, 08:23

malloc
Народ, кто-нить может объяснить какие есть недостатки у этой функции, всегда юзал, а тут говорят,...

new, malloc,
Добрый день. При роботе с дин. памяттю в конец выделяемой памяти добавляеться какойто бред, чтото...

new на malloc
Измените выделение памяти на C - malloc,и почему у меня не открывает текстовый файл? #include...

Malloc си
распределить память для массива из 80 символов с помощью функции malloc. Прочитать в эту память...


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

Или воспользуйтесь поиском по форуму:
34
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru