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

Выделение памяти с помощью new под объекты без вызова их конструкторов - C++

Войти
Регистрация
Восстановить пароль
 
 
tapochka
34 / 34 / 8
Регистрация: 25.04.2014
Сообщений: 449
13.07.2015, 01:33     Выделение памяти с помощью new под объекты без вызова их конструкторов #1
здравствуйте, корректен ли следующий код:
C++
1
2
3
4
5
6
7
8
9
10
11
myClass* pttr = static_cast<myClass*>(::operator new[](5 * sizeof(myClass)));
for (int i = 0; i < 5; i++){
      new(pttr+i) myClass();
}
 
::operator new[](2*sizeof(myClass),pttr + 5);
 
for (int i = 0; i < 5; i++){
     (pttr + i)->~myClass();
}
::operator delete[](pttr);
т.е. в конце освобождается вся память или только на 5 элементов?
Лучшие ответы (1)
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
13.07.2015, 01:33     Выделение памяти с помощью new под объекты без вызова их конструкторов
Посмотрите здесь:

C++ Выделение памяти под переменную
C++ Порядок вызова конструкторов
Выделение памяти под массив объектов без вызова конструктора C++
C++ Выделение памяти под структуру
Выделение памяти под массивы C++
C++ Выделение статической памяти, не используя статические объекты
Выделение памяти под структуру C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Renji
1622 / 1070 / 261
Регистрация: 05.06.2014
Сообщений: 3,166
13.07.2015, 02:40     Выделение памяти с помощью new под объекты без вызова их конструкторов #2
Цитата Сообщение от tapochka Посмотреть сообщение
т.е. в конце освобождается вся память или только на 5 элементов?
Какая "вся"? ::operator new[](2*sizeof(myClass),pttr + 5); же ничего не выделяет и просто возвращает переданный ему указатель.
tapochka
34 / 34 / 8
Регистрация: 25.04.2014
Сообщений: 449
13.07.2015, 02:46  [ТС]     Выделение памяти с помощью new под объекты без вызова их конструкторов #3
Renji, хмммм... почему тогда тут память выделяется
C++
1
myClass* pttr = static_cast<myClass*>(::operator new[](5 * sizeof(myClass)));
а тут
C++
1
::operator new[](2*sizeof(myClass),pttr + 5)
нет?
Renji
1622 / 1070 / 261
Регистрация: 05.06.2014
Сообщений: 3,166
13.07.2015, 03:11     Выделение памяти с помощью new под объекты без вызова их конструкторов #4
Видимо, для единообразия.
Запись new myClass[5] выделяет память вызовом operator new, а затем вызывает пять конструкторов.
Запись new (ptr) myClass[5] предполагает что память уже выделена и нужно только вызвать пять конструкторов.

Вот и получается что когда второй вариант вызывает operator new, operator new остаются только функции заглушки, которая фактически абсолютно ничего не делает.
tapochka
34 / 34 / 8
Регистрация: 25.04.2014
Сообщений: 449
13.07.2015, 03:17  [ТС]     Выделение памяти с помощью new под объекты без вызова их конструкторов #5
Цитата Сообщение от Renji Посмотреть сообщение
Вот и получается что когда второй вариант вызывает operator new, operator new остаются только функции заглушки, которая фактически абсолютно ничего не делает.
честно говоря не пойму никак почему память не выделяется...
как тогда просто аллоцировать память без вызова конструкторов объектов?
Renji
1622 / 1070 / 261
Регистрация: 05.06.2014
Сообщений: 3,166
13.07.2015, 03:26     Выделение памяти с помощью new под объекты без вызова их конструкторов #6
Цитата Сообщение от tapochka Посмотреть сообщение
честно говоря не пойму никак почему память не выделяется...
как тогда просто аллоцировать память без вызова конструкторов объектов?
Потому что operator new[](size_t,void*) вызывается не для выделения памяти, а чисто для отчетности: программист написал new, указал при этом что память сам выделит, но порядок быть должон! Раз есть new, надо сделать вызов operator new. Пусть даже этот вызов не делает ни шиша.

А просто аллоцировать память можно через malloc, освобождать через free, менять размер выделенного блока через realloc.
tapochka
34 / 34 / 8
Регистрация: 25.04.2014
Сообщений: 449
13.07.2015, 03:32  [ТС]     Выделение памяти с помощью new под объекты без вызова их конструкторов #7
Renji, напишем, допустим, так:
C++
1
2
3
4
myClass* pttr = static_cast<myClass*>(::operator new[](5 * sizeof(myClass)));
for (int i = 0; i < 2; i++){
      new(pttr+i) myClass();
}
разве аллоцированный блок не будет равен 5 myClass, а конструкторы сработают только у двух?

Цитата Сообщение от Renji Посмотреть сообщение
А просто аллоцировать память можно через malloc, освобождать через free, менять размер выделенного блока через realloc.
а если средствами c++?
Renji
1622 / 1070 / 261
Регистрация: 05.06.2014
Сообщений: 3,166
13.07.2015, 03:41     Выделение памяти с помощью new под объекты без вызова их конструкторов #8
Цитата Сообщение от tapochka Посмотреть сообщение
разве аллоцированный блок не будет равен 5 myClass, а конструкторы сработают только у двух?
Да и что? Мы вроде бы говорили о выделении памяти, а не вызове конструкторов. Вторым operator new не занимается. Он как бы не синоним new.
Цитата Сообщение от tapochka Посмотреть сообщение
а если средствами c++?
Вызвать operator new с одним аргументом. Только какой в этом смысл, если в 99% случаев operator new - синоним malloc (еще 1% - шаманства с перегрузкой операторов)? Ну, с поправкой на кидание исключений.
tapochka
34 / 34 / 8
Регистрация: 25.04.2014
Сообщений: 449
13.07.2015, 03:51  [ТС]     Выделение памяти с помощью new под объекты без вызова их конструкторов #9
Цитата Сообщение от Renji Посмотреть сообщение
Вызвать operator new с одним аргументом
можете написать корректный код пожалуйста... я не понимаю
Renji
1622 / 1070 / 261
Регистрация: 05.06.2014
Сообщений: 3,166
13.07.2015, 03:53     Выделение памяти с помощью new под объекты без вызова их конструкторов #10
Цитата Сообщение от tapochka Посмотреть сообщение
можете написать корректный код пожалуйста... я не понимаю
C++
1
void*ptr=operator new(sizeof(myClass));
Но повторюсь, это тоже самое что malloc, плюс мизерная (если внезапно кончится память) вероятность получить исключением в лоб.
tapochka
34 / 34 / 8
Регистрация: 25.04.2014
Сообщений: 449
13.07.2015, 03:58  [ТС]     Выделение памяти с помощью new под объекты без вызова их конструкторов #11
Цитата Сообщение от Renji Посмотреть сообщение
Но повторюсь, это тоже самое что malloc, плюс мизерная (если внезапно кончится память) вероятность получить исключением в лоб.
не совсем то... если не сложно, напишите пожалуйста как сделать первый пример корректно через operator new
Renji
1622 / 1070 / 261
Регистрация: 05.06.2014
Сообщений: 3,166
13.07.2015, 04:07     Выделение памяти с помощью new под объекты без вызова их конструкторов #12
Сообщение было отмечено автором темы, экспертом или модератором как ответ
Цитата Сообщение от tapochka Посмотреть сообщение
не совсем то... если не сложно, напишите пожалуйста как сделать первый пример корректно через operator new
В смысле изменить размер выделенного блока? Никак. Массив переменного размера делается через std::vector, но это уже не низкоуровневое управление выделением памяти.
C++
1
2
3
4
vector<myClass> array(5);//создается массив на пять элементов
array.resize(7);//превращается в массив на семь
array.push_back(myClass());//увеличивается на один элемент
array.emplace_back();//и еще на элемент, но это уже C++11
tapochka
34 / 34 / 8
Регистрация: 25.04.2014
Сообщений: 449
13.07.2015, 04:36  [ТС]     Выделение памяти с помощью new под объекты без вызова их конструкторов #13
Цитата Сообщение от Renji Посмотреть сообщение
Массив переменного размера делается через std::vector
так я понять одного не могу: вектор же как-то реализован?) я вот как раз мучаюсь уже долгое время, хочу свой вектор создать с этими всеми resize-ми, всеми видами конструкторов 11 стандарта и итераторами. нормальной понятной реализации нигде не видел. уж и через std::allocator пытался и просто через new... метод resize вызвал неимоверную сложность, на нем все обрывается. однако в векторе он реализован как то...

Цитата Сообщение от Renji Посмотреть сообщение
В смысле изменить размер выделенного блока? Никак.
честно говоря я в это поверить не могу никак...

Добавлено через 14 минут
отдельное спасибо за emplace_back
Renji
1622 / 1070 / 261
Регистрация: 05.06.2014
Сообщений: 3,166
13.07.2015, 04:40     Выделение памяти с помощью new под объекты без вызова их конструкторов #14
Цитата Сообщение от tapochka Посмотреть сообщение
так я понять одного не могу: вектор же как-то реализован?)
А там схалтурили. Вектор просто хапает памяти с запасом (метод reserve. Размер запаса можно посмотреть через capacity) и расширяет массив за счет этого запаса. Когда же запас кончается, приходится создать новый массив и скопировать в него старый, так как аллокаторы аналога resize не имеют. Хотя, его вполне можно было бы и сделать, предусмотрев в нем какой ни будь callback на случай если resize приводит к перемещению массива с места на место.
Цитата Сообщение от tapochka Посмотреть сообщение
честно говоря я в это поверить не могу никак...
Ну а смысл вводить "новое" средство C++, если его функциональность будет на 99% совпадать с функциональностью старого сишного realloc?
tapochka
34 / 34 / 8
Регистрация: 25.04.2014
Сообщений: 449
13.07.2015, 04:54  [ТС]     Выделение памяти с помощью new под объекты без вызова их конструкторов #15
Цитата Сообщение от Renji Посмотреть сообщение
А там схалтурили. Вектор просто хапает памяти с запасом (метод reserve. Размер запаса можно посмотреть через capacity) и расширяет массив за счет этого запаса. Когда же запас кончается, приходится создать новый массив и скопировать в него старый, так как аллокаторы аналога resize не имеют.
мне не понятно почему это работает:
C++
1
2
std::vector<char> vector(5);
vector.reserve(1000);
вначале и size и capacity равный по 5(visual studio 2013). потом size остался 5, а capacity стала 1000... значит ведь как-то выделенный блок изменяется
Renji
1622 / 1070 / 261
Регистрация: 05.06.2014
Сообщений: 3,166
13.07.2015, 05:02     Выделение памяти с помощью new под объекты без вызова их конструкторов #16
Цитата Сообщение от tapochka Посмотреть сообщение
мне не понятно почему это работает:
И что непонятно? Выделен (capacity) массив на тысячу элементов, из них использовано (size) пять. Остальные про запас лежат.
tapochka
34 / 34 / 8
Регистрация: 25.04.2014
Сообщений: 449
13.07.2015, 05:07  [ТС]     Выделение памяти с помощью new под объекты без вызова их конструкторов #17
Цитата Сообщение от Renji Посмотреть сообщение
Выделен (capacity) массив на тысячу элементов, из них использовано (size) пять. Остальные про запас лежат.
вы же написали, что изменить размер выделенного блока нельзя... однако у нас сначала был блок на 5, потом блок на 1000...
неужели вектор через realloc реализован?
Renji
1622 / 1070 / 261
Регистрация: 05.06.2014
Сообщений: 3,166
13.07.2015, 05:10     Выделение памяти с помощью new под объекты без вызова их конструкторов #18
Цитата Сообщение от tapochka Посмотреть сообщение
вы же написали, что изменить размер выделенного блока нельзя... однако у нас сначала был блок на 5, потом блок на 1000
Я же сказал "приходится создать новый массив и скопировать в него старый".
C++
1
2
3
4
5
6
7
int*ptr=new int[5];
for(int i=0;i<5;++i)
    ptr[i]=i;
int*temp=new int[7];
copy(ptr,ptr+5,temp);
delete[]ptr;
ptr=temp;
tapochka
34 / 34 / 8
Регистрация: 25.04.2014
Сообщений: 449
13.07.2015, 05:12  [ТС]     Выделение памяти с помощью new под объекты без вызова их конструкторов #19
Цитата Сообщение от Renji Посмотреть сообщение
Я же сказал "приходится создать новый массив и скопировать в него старый".
я думал так лишь push_back реализован, а тут оказывается и reserve тоже
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
13.07.2015, 05:15     Выделение памяти с помощью new под объекты без вызова их конструкторов
Еще ссылки по теме:

Выделение памяти под матрицу C++
C++ Выделение памяти под матрицу
Выделение памяти под указатель C++
Перераспределение памяти с new под объекты C++
C++ Порядок вызова конструкторов

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

Или воспользуйтесь поиском по форуму:
Renji
1622 / 1070 / 261
Регистрация: 05.06.2014
Сообщений: 3,166
13.07.2015, 05:15     Выделение памяти с помощью new под объекты без вызова их конструкторов #20
Цитата Сообщение от tapochka Посмотреть сообщение
я думал так лишь push_back реализован, а тут оказывается и reserve тоже
Ну так повторяю, вектор выделяет память через функции предоставленные аллокатором. А там просто не предусмотрели аналога resize. То есть, если даже менеджер управления памятью resize поддерживает, вектор о его существовании ничего не знает и знать не может.
Yandex
Объявления
13.07.2015, 05:15     Выделение памяти с помощью new под объекты без вызова их конструкторов
Ответ Создать тему
Опции темы

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