Форум программистов, компьютерный форум, киберфорум
C++
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 4.89/9: Рейтинг темы: голосов - 9, средняя оценка - 4.89
42 / 42 / 17
Регистрация: 25.04.2014
Сообщений: 499
1

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

13.07.2015, 01:33. Показов 1820. Ответов 23
Метки нет (Все метки)

здравствуйте, корректен ли следующий код:
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 элементов?
0

Помощь в написании контрольных, курсовых и дипломных работ здесь.

Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
13.07.2015, 01:33
Ответы с готовыми решениями:

Выделение памяти под массив объектов без вызова конструктора
Добрый вечер. Насколько я знаю, при выделении памяти под массив объектов, для каждого из них...

Выделение памяти под объекты классов
Здравствуйте, начал недавно осваивать классы и вот у меня в голове все крутится один вопрос. Каким...

Динамическое выделение памяти под объекты
Создать класс с именем TRAIN, содержащий следующие закрытые поля: • название пункта назначения;...

Выделение статической памяти, не используя статические объекты
Здравствуйте! Как известно, когда мы объявляем статическую переменную, то компилятор выделяет ей...

23
2723 / 1887 / 559
Регистрация: 05.06.2014
Сообщений: 5,499
13.07.2015, 02:40 2
Цитата Сообщение от tapochka Посмотреть сообщение
т.е. в конце освобождается вся память или только на 5 элементов?
Какая "вся"? ::operator new[](2*sizeof(myClass),pttr + 5); же ничего не выделяет и просто возвращает переданный ему указатель.
0
42 / 42 / 17
Регистрация: 25.04.2014
Сообщений: 499
13.07.2015, 02:46  [ТС] 3
Renji, хмммм... почему тогда тут память выделяется
C++
1
myClass* pttr = static_cast<myClass*>(::operator new[](5 * sizeof(myClass)));
а тут
C++
1
::operator new[](2*sizeof(myClass),pttr + 5)
нет?
0
2723 / 1887 / 559
Регистрация: 05.06.2014
Сообщений: 5,499
13.07.2015, 03:11 4
Видимо, для единообразия.
Запись new myClass[5] выделяет память вызовом operator new, а затем вызывает пять конструкторов.
Запись new (ptr) myClass[5] предполагает что память уже выделена и нужно только вызвать пять конструкторов.

Вот и получается что когда второй вариант вызывает operator new, operator new остаются только функции заглушки, которая фактически абсолютно ничего не делает.
0
42 / 42 / 17
Регистрация: 25.04.2014
Сообщений: 499
13.07.2015, 03:17  [ТС] 5
Цитата Сообщение от Renji Посмотреть сообщение
Вот и получается что когда второй вариант вызывает operator new, operator new остаются только функции заглушки, которая фактически абсолютно ничего не делает.
честно говоря не пойму никак почему память не выделяется...
как тогда просто аллоцировать память без вызова конструкторов объектов?
0
2723 / 1887 / 559
Регистрация: 05.06.2014
Сообщений: 5,499
13.07.2015, 03:26 6
Цитата Сообщение от tapochka Посмотреть сообщение
честно говоря не пойму никак почему память не выделяется...
как тогда просто аллоцировать память без вызова конструкторов объектов?
Потому что operator new[](size_t,void*) вызывается не для выделения памяти, а чисто для отчетности: программист написал new, указал при этом что память сам выделит, но порядок быть должон! Раз есть new, надо сделать вызов operator new. Пусть даже этот вызов не делает ни шиша.

А просто аллоцировать память можно через malloc, освобождать через free, менять размер выделенного блока через realloc.
0
42 / 42 / 17
Регистрация: 25.04.2014
Сообщений: 499
13.07.2015, 03:32  [ТС] 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++?
0
2723 / 1887 / 559
Регистрация: 05.06.2014
Сообщений: 5,499
13.07.2015, 03:41 8
Цитата Сообщение от tapochka Посмотреть сообщение
разве аллоцированный блок не будет равен 5 myClass, а конструкторы сработают только у двух?
Да и что? Мы вроде бы говорили о выделении памяти, а не вызове конструкторов. Вторым operator new не занимается. Он как бы не синоним new.
Цитата Сообщение от tapochka Посмотреть сообщение
а если средствами c++?
Вызвать operator new с одним аргументом. Только какой в этом смысл, если в 99% случаев operator new - синоним malloc (еще 1% - шаманства с перегрузкой операторов)? Ну, с поправкой на кидание исключений.
0
42 / 42 / 17
Регистрация: 25.04.2014
Сообщений: 499
13.07.2015, 03:51  [ТС] 9
Цитата Сообщение от Renji Посмотреть сообщение
Вызвать operator new с одним аргументом
можете написать корректный код пожалуйста... я не понимаю
0
2723 / 1887 / 559
Регистрация: 05.06.2014
Сообщений: 5,499
13.07.2015, 03:53 10
Цитата Сообщение от tapochka Посмотреть сообщение
можете написать корректный код пожалуйста... я не понимаю
C++
1
void*ptr=operator new(sizeof(myClass));
Но повторюсь, это тоже самое что malloc, плюс мизерная (если внезапно кончится память) вероятность получить исключением в лоб.
0
42 / 42 / 17
Регистрация: 25.04.2014
Сообщений: 499
13.07.2015, 03:58  [ТС] 11
Цитата Сообщение от Renji Посмотреть сообщение
Но повторюсь, это тоже самое что malloc, плюс мизерная (если внезапно кончится память) вероятность получить исключением в лоб.
не совсем то... если не сложно, напишите пожалуйста как сделать первый пример корректно через operator new
0
2723 / 1887 / 559
Регистрация: 05.06.2014
Сообщений: 5,499
13.07.2015, 04:07 12
Лучший ответ Сообщение было отмечено tapochka как решение

Решение

Цитата Сообщение от 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
1
42 / 42 / 17
Регистрация: 25.04.2014
Сообщений: 499
13.07.2015, 04:36  [ТС] 13
Цитата Сообщение от Renji Посмотреть сообщение
Массив переменного размера делается через std::vector
так я понять одного не могу: вектор же как-то реализован?) я вот как раз мучаюсь уже долгое время, хочу свой вектор создать с этими всеми resize-ми, всеми видами конструкторов 11 стандарта и итераторами. нормальной понятной реализации нигде не видел. уж и через std::allocator пытался и просто через new... метод resize вызвал неимоверную сложность, на нем все обрывается. однако в векторе он реализован как то...

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

Добавлено через 14 минут
отдельное спасибо за emplace_back
0
2723 / 1887 / 559
Регистрация: 05.06.2014
Сообщений: 5,499
13.07.2015, 04:40 14
Цитата Сообщение от tapochka Посмотреть сообщение
так я понять одного не могу: вектор же как-то реализован?)
А там схалтурили. Вектор просто хапает памяти с запасом (метод reserve. Размер запаса можно посмотреть через capacity) и расширяет массив за счет этого запаса. Когда же запас кончается, приходится создать новый массив и скопировать в него старый, так как аллокаторы аналога resize не имеют. Хотя, его вполне можно было бы и сделать, предусмотрев в нем какой ни будь callback на случай если resize приводит к перемещению массива с места на место.
Цитата Сообщение от tapochka Посмотреть сообщение
честно говоря я в это поверить не могу никак...
Ну а смысл вводить "новое" средство C++, если его функциональность будет на 99% совпадать с функциональностью старого сишного realloc?
1
42 / 42 / 17
Регистрация: 25.04.2014
Сообщений: 499
13.07.2015, 04:54  [ТС] 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... значит ведь как-то выделенный блок изменяется
0
2723 / 1887 / 559
Регистрация: 05.06.2014
Сообщений: 5,499
13.07.2015, 05:02 16
Цитата Сообщение от tapochka Посмотреть сообщение
мне не понятно почему это работает:
И что непонятно? Выделен (capacity) массив на тысячу элементов, из них использовано (size) пять. Остальные про запас лежат.
0
42 / 42 / 17
Регистрация: 25.04.2014
Сообщений: 499
13.07.2015, 05:07  [ТС] 17
Цитата Сообщение от Renji Посмотреть сообщение
Выделен (capacity) массив на тысячу элементов, из них использовано (size) пять. Остальные про запас лежат.
вы же написали, что изменить размер выделенного блока нельзя... однако у нас сначала был блок на 5, потом блок на 1000...
неужели вектор через realloc реализован?
0
2723 / 1887 / 559
Регистрация: 05.06.2014
Сообщений: 5,499
13.07.2015, 05:10 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;
1
42 / 42 / 17
Регистрация: 25.04.2014
Сообщений: 499
13.07.2015, 05:12  [ТС] 19
Цитата Сообщение от Renji Посмотреть сообщение
Я же сказал "приходится создать новый массив и скопировать в него старый".
я думал так лишь push_back реализован, а тут оказывается и reserve тоже
0
2723 / 1887 / 559
Регистрация: 05.06.2014
Сообщений: 5,499
13.07.2015, 05:15 20
Цитата Сообщение от tapochka Посмотреть сообщение
я думал так лишь push_back реализован, а тут оказывается и reserve тоже
Ну так повторяю, вектор выделяет память через функции предоставленные аллокатором. А там просто не предусмотрели аналога resize. То есть, если даже менеджер управления памятью resize поддерживает, вектор о его существовании ничего не знает и знать не может.
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
13.07.2015, 05:15

Перераспределение памяти с new под объекты
есть класс #include &lt;iostream&gt; #include &lt;string&gt; using namespace std; class tel_book {...

Выделение памяти с помощью функции realloc
в общем задачка по сути своей вроде бы легкая, должна укладываться в 60 строчек, но что-то допереть...

Порядок вызова конструкторов
Всем доброго дня. Наткнулся в коде на интересные грабли: test.cpp #include &quot;test.h&quot; Test...

Порядок вызова конструкторов
на срр-reference нашёл тему про виртуальный деструктор, но я так и не понял (да там и не...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2021, vBulletin Solutions, Inc.