Форум программистов, компьютерный форум, киберфорум
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Mikhail1990
19 / 19 / 4
Регистрация: 22.03.2014
Сообщений: 222
#1

Объясните как выделяется память под умные указатели - C++

15.08.2015, 13:59. Просмотров 750. Ответов 21
Метки нет (Все метки)

Читаю книгу Праты, не могу понять этот абзац, а точнее применение операторов new [] и new и delete[] и delete с ними.

Объект auto_ptr или shared_ptr должен использоваться только для памяти,
выделенной операцией new. Память, выделенная с помощью new [ ], не подходит. Нельзя применять
auto_ptr, shared_ptr или unique_ptr для памяти, выделенной посредством операции
new либо, в случае unique_ptr, с помощью new или new [ ].
Почему нельзя применять new[].
0
Лучшие ответы (1)
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
15.08.2015, 13:59
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Объясните как выделяется память под умные указатели (C++):

Как выделяется память под массив string? - C++
В общем читаю книжку, там объявлены два массива int* p = new int, int* v = new string... бла бла бла ....а потом -> ...После резервирования...

Умные указатели - C++
#include <fstream> #include <algorithm> #include <vector> #include <iostream> #include <memory> using namespace std; ...

Умные указатели - C++
Пишу класс дерево поиска:template<typename T, typename Compare> class AvlTree { private: struct Node { T...

Умные указатели - C++
Здравствуйте! вопрос указатель auto_ptr почитала литературу, там написано он считывает и удаляет ссылки, т.е. он получает какие-то...

Умные указатели - C++
Правильно ли я понял, что умный указатель - это просто шаблон класса, содержащий в себе указатель Type *p и его delete в деструкторе?

Умные указатели - C++
Насколько я понял для того что бы предотвратить передачу права владения используют const. Код из примера: template <class T> ...

21
PavelPol
44 / 44 / 17
Регистрация: 05.11.2014
Сообщений: 196
15.08.2015, 14:17 #2
Указанные операторы могут работать только с одним объектом и сами освобождают выделенную память. В случае с new[] выделяется массив объектов и алгоритмы для освобождения другие. Плюс к тому, эти "умные указатели" запускают конструктор и деструктор у объекта.
1
Mikhail1990
19 / 19 / 4
Регистрация: 22.03.2014
Сообщений: 222
15.08.2015, 14:22  [ТС] #3
PavelPol, а можно наглядный примерчик? И
unique_ptr
умеет работать с
new []
.
0
tnk500
113 / 117 / 25
Регистрация: 25.08.2012
Сообщений: 1,292
Завершенные тесты: 3
15.08.2015, 14:23 #4
Mikhail1990, потому что у деструкторов умных указателей вызывается delete, а не delete[], как должно быть в случае массивов. А у unique_ptr есть конструктор/деструктор для объектов-массивов. Создается как
C++
1
std::unique_ptr<SomeClass[]> as(new SomeClass[4]);
1
Mikhail1990
19 / 19 / 4
Регистрация: 22.03.2014
Сообщений: 222
15.08.2015, 14:45  [ТС] #5
tnk500, В книге вот такой пример который тоже верный
std::unique_ptr< double[]>pda(new double(5)); // будет использовать delete []
так ли это?

Добавлено через 10 минут
tnk500, и оператор new или new [ ] я не могу использовать с shared_ptr and auto_ptr, верно?
0
hoggy
6701 / 2883 / 494
Регистрация: 15.11.2014
Сообщений: 6,480
Завершенные тесты: 1
15.08.2015, 15:59 #6
Цитата Сообщение от Mikhail1990 Посмотреть сообщение
должен использоваться только для памяти,
выделенной операцией new.
ложь.

Цитата Сообщение от Mikhail1990 Посмотреть сообщение
Память, выделенная с помощью new [ ]
std::unique_ptr умеет работать с массивами.
так что, это тоже - ложь.

Добавлено через 1 минуту
Цитата Сообщение от Mikhail1990 Посмотреть сообщение
std::unique_ptr< double[]>pda(new double(5)); // будет использовать delete []
это - UB
1
tnk500
113 / 117 / 25
Регистрация: 25.08.2012
Сообщений: 1,292
Завершенные тесты: 3
15.08.2015, 16:16 #7
Лучший ответ Сообщение было отмечено автором темы, экспертом или модератором как ответ
Mikhail1990,
1. Так сделать можно, но нельзя: вы инициализируете указатель как указатель на массив, следовательно, можете, кхм... скакать по памяти с помощью него. Поэтому разницы между таким определением и определением нормальным вы не заметите, во всяком случае, пока во время инициализации массива не схватите access violation или еще что-нибудь. Ну а там очистка ресурсов еще вызовет вопросов.
2. Верно.
1
ct0r
Игогошка!
1776 / 678 / 42
Регистрация: 19.08.2012
Сообщений: 1,294
Завершенные тесты: 1
15.08.2015, 16:46 #8
Цитата Сообщение от tnk500 Посмотреть сообщение
2. Верно.
shared_ptr нормально работает с массивами, было бы желание.

C++
1
std::shared_ptr<Foo> sp(new Foo[10], [](Foo * p) { delete[] p; });
0
tnk500
113 / 117 / 25
Регистрация: 25.08.2012
Сообщений: 1,292
Завершенные тесты: 3
15.08.2015, 16:50 #9
ct0r, неужели? А обращаться к элементам как будете?) Одним делитером дело не может ограничиться.
0
hoggy
6701 / 2883 / 494
Регистрация: 15.11.2014
Сообщений: 6,480
Завершенные тесты: 1
15.08.2015, 16:56 #10
Цитата Сообщение от tnk500 Посмотреть сообщение
неужели? А обращаться к элементам как будете?
вы пишите это так, словно вам трудно самому догадаться:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <iostream>
#include <memory>
 
 
struct some
{
    some() { std::cout<<"ctor\n"; }
   ~some() { std::cout<<"dtor\n"; }
    
    void set(const int v) { mV = v; }
    
    int mV;
};
 
int main()
{
    std::cout << "Hello, world!\n";
    
    std::shared_ptr<some> 
        smart(new some[10], [](some* const p) { delete[] p; });
    
    (smart.get() + 1)->set(10);
    
}
0
tnk500
113 / 117 / 25
Регистрация: 25.08.2012
Сообщений: 1,292
Завершенные тесты: 3
15.08.2015, 17:01 #11
hoggy, я ж говорю — одним делитером дело не ограничится. Но ведь и вы понимаете, почему так делать не нужно)
0
ct0r
Игогошка!
1776 / 678 / 42
Регистрация: 19.08.2012
Сообщений: 1,294
Завершенные тесты: 1
15.08.2015, 17:08 #12
Цитата Сообщение от tnk500 Посмотреть сообщение
ct0r, неужели? А обращаться к элементам как будете?) Одним делитером дело не может ограничиться.
Факт остается фактом. shared_ptr может спокойно хранить массив. Обращаться через сырой пойнтер конечно же.

Я, кстати, немного перемудрил. Можно даже так:
C++
1
std::shared_ptr<Foo> sp(new Foo[10], std::default_delete<Foo[]>());
Добавлено через 5 минут
Цитата Сообщение от tnk500 Посмотреть сообщение
почему так делать не нужно
Нужно-нужно. Ты думаешь operator[] у unique_ptr что-то особенное делает? Он делает тот же get()[i].
0
tnk500
113 / 117 / 25
Регистрация: 25.08.2012
Сообщений: 1,292
Завершенные тесты: 3
15.08.2015, 17:10 #13
ct0r, поэтому и не нужно. Вы работали в коллективе? Вряд ли такой форме индексации обрадуются ваши коллеги...
0
ct0r
Игогошка!
1776 / 678 / 42
Регистрация: 19.08.2012
Сообщений: 1,294
Завершенные тесты: 1
15.08.2015, 17:19 #14
Цитата Сообщение от tnk500 Посмотреть сообщение
ct0r, поэтому и не нужно. Вы работали в коллективе? Вряд ли такой форме индексации обрадуются ваши коллеги...
Обойдемся без телепатии? Это ваше субъективное мнение. А объективное заключается в том, что shared_ptr работает с массивами и точка. Это я показал кодом.
0
gromo
371 / 270 / 24
Регистрация: 04.09.2009
Сообщений: 1,214
15.08.2015, 17:33 #15
tnk500, since C++17 будет добавлена стандартная специализация shared_ptr/weak_ptr для массивов, так что такое "безобразное" обращение к элементам массива будет узаконено стандартом.
2
15.08.2015, 17:33
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
15.08.2015, 17:33
Привет! Вот еще темы с ответами:

умные указатели - C++
у меня например есть куча юнитов, у каждого из них есть указатель на игровой ресурс (допустим камень). Есть такая задумка: когда камень...

Прата и умные указатели - C++
Читаю Прата С. - Язык программирования С++. Лекции и упражнения - 2011, стр. 886: Пишу, компилирую - получаю ошибки: Кто не прав...

Как выделяется память на стеке и на куче? Когда нужна ручная очистка? - C++
Всем здрасьте. //1 char s = 's'; //2 char* ss = new char; Во втором случае компилятор выделяет участок памяти, потом мне же её...

Умные указатели на структуру с шаблоном - C++
#pragma once #include &lt;vector&gt; #include &lt;memory&gt; using namespace std; template &lt;class T&gt; struct Selem ...


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

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

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