Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.87/15: Рейтинг темы: голосов - 15, средняя оценка - 4.87
0 / 0 / 0
Регистрация: 16.07.2015
Сообщений: 7

Стратегия выделения/освобождения памяти

16.07.2015, 22:12. Показов 3262. Ответов 23
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
здравствуйте господа. есть такой вопрос. пусть есть класс например Bitmap - несжатое растровое изображение. Пусть необходимо уметь считывать этот bitmap из файлов различных форматов. пусть за работу с каждым форматом отвечает свой класс. например IoBmp, IoTiff, IoPng. например за считывание битмапа из IoBmp отвечает какой-нибудь статический метод IoBmp::open(const std::string &fileName). вопрос как бы поудобнее это дело организовать. именно, если сделать так:
C++
1
2
3
4
static Bitmap IoBmp::open(/*...*/) {
    //...
    return Bitmap(/*...*/);
}
битмап нельзя будет считать в кучу (Bitmap* bmp = new Bitmap(IoBmp::open(...)) не в счет - не хочется копировать растр. хотя?...). если
C++
1
2
3
4
static Bitmap* IoBmp::open(/*...*/) {
    //...
    return new Bitmap(/*...*/);
}
память под битмап будет динамически выделена внутри этого open и удалить мы его вообще говоря не сможем. конечно, delete bmp; вне метода open сработает, но так делать нельзя.
так и тянет написать что-то вроде
C++
1
2
3
void Bitmap::free() {
    delete this;
}
чтоб получилось
C++
1
2
Bitmap* bmp = IoBmp::open(fileName); //IoBmp знает как выделена память
bmp->free(); //Bitmap знает как ее освободить. внешней программе пофиг,но все равно нехорошо как-то
можно ли так делать?
или так?
C++
1
2
3
4
5
static void IoBmp::free(Bitmap* bmp) {
    delete bmp;
}
Bitmap* bmp = IoBmp::open(fileName);
IoBmp::free(bmp);
ну и как вариант сделать что-то вроде того:
C++
1
2
3
4
5
static size_t IoBmp::getSize(const std::string &fileName);
static void IoBmp::open(Bitmap* bmp, const std::string &fileName);
Bitmap* bmp = new Bitmap(IoBmp::getSize(fileName)); //выделяем память под битмап по данным из файла
IoBmp::open(bmp, fileName); //читаем из файла растр
delete bmp;
и все довольны. но как-то куцо и неудобно выходит. чего-то я вообще не знаю как поступить. вопрос наверно бредовый, но уж помогите)
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
16.07.2015, 22:12
Ответы с готовыми решениями:

Нюансы выделения и освобождения памяти (структуры)
struct point { int a; point *next; } point *p=new point Я освобожу всю память которая отводилась под динам. структуру? delete...

Функциии динамического выделения и освобождения памяти
Необходим написать функции выделения и освобождения памяти под двумерный динамический массив. Причем освобождение должн быть не сразу для...

Написать функции для работы с массивом - выделения/освобождения памяти, консольного ввода/вывода
Напишите функции: 1) выделяющую память для массива данных типа float, 2) заполняющую ячейки данными с клавиатуры, 3) выводящую...

23
2784 / 1937 / 570
Регистрация: 05.06.2014
Сообщений: 5,602
16.07.2015, 22:34
C++
1
2
3
4
5
6
7
8
class abstract_image
{
public:
    virtual ~abstract_image(){}
    virtual int height()const=0;//высота
    virtual int width()const=0;//ширина
    virtual int color(int x,int y)const=0;//цвет конкретной точки
};
Все прочие классы наследуются от данного.
1
Диванный эксперт
Эксперт С++
 Аватар для Max Dark
2550 / 2064 / 971
Регистрация: 09.10.2013
Сообщений: 4,793
Записей в блоге: 4
16.07.2015, 22:59
Может стоит применить std::shared_ptr/std::unique_ptr?
C++
1
2
3
4
5
6
7
8
9
10
11
using BitmapPtr = std::unique_ptr<Bitmap>;
//...
static Bitmap* IoBmp::open(/*...*/) {
    //...
    return new Bitmap(/*...*/);
}
//....
BitmapPtr bmp(IoBmp::open(/*...*/));
// работаем с bmp как с обычным указателем
bmp->Draw(device);
// Память автоматически освобождается
1
Неэпический
 Аватар для Croessmah
18144 / 10728 / 2066
Регистрация: 27.09.2012
Сообщений: 27,026
Записей в блоге: 1
16.07.2015, 23:23
Цитата Сообщение от просто_спросить Посмотреть сообщение
память под битмап будет динамически выделена внутри этого open и удалить мы его вообще говоря не сможем. конечно, delete bmp; вне метода open сработает, но так делать нельзя.
Почему? Так работают фабрики
1
0 / 0 / 0
Регистрация: 16.07.2015
Сообщений: 7
16.07.2015, 23:55  [ТС]
> Может стоит применить std::shared_ptr/std::unique_ptr?
спасибо за совет! только не снизит ли это производительность? хотя,наверняка очень незначительно. но еще выходит,что если программа будет вызывать open(...) для обычных указателей, то за корректность работы никто не отвечает? хотя можно и как-то так
C++
1
static std::unique_ptr< Bitmap > IoBmp::open(/*...*/);
и все-таки навязывать использование умных указателей изза такой пустяковой проблемы кажется как-то недемократично
неужели все так серьезно?
а среди вышепредложенных вариантов вообще ни одного корректного нет? даже с getSize(...)?
> Почему? Так работают фабрики
а как же правило "кто память выделяет,тот и освобождает"? или если заранее оговорить,что во всех open'ах память выделяется через new, то такой вариант допустим?
0
Неэпический
 Аватар для Croessmah
18144 / 10728 / 2066
Регистрация: 27.09.2012
Сообщений: 27,026
Записей в блоге: 1
17.07.2015, 00:45
Цитата Сообщение от просто_спросить Посмотреть сообщение
а как же правило "кто память выделяет,тот и освобождает"? или если заранее оговорить,что во всех open'ах память выделяется через new, то такой вариант допустим?
Почитайте о паттерне "фабрика объектов", станет понятнее
1
0 / 0 / 0
Регистрация: 16.07.2015
Сообщений: 7
17.07.2015, 01:37  [ТС]
Цитата Сообщение от Croessmah Посмотреть сообщение
Почитайте о паттерне "фабрика объектов"
глянул мельком. спасибо. появился наконец повод узнать, что такое фабрика и зачем она нужна. ну а по вопросу - где-то используют умные указатели, а где-то и правда не парятся. чего-то я совсем запутался.. с одной стороны по-хорошему память должен освобождать тот, кто выделил (или это ложные слухи?), с другой - масса примеров исходников фабрик, где на это правило кладут и даже не упоминают.. а правда то в чем?
0
Диванный эксперт
Эксперт С++
 Аватар для Max Dark
2550 / 2064 / 971
Регистрация: 09.10.2013
Сообщений: 4,793
Записей в блоге: 4
17.07.2015, 01:40
Освобождать должен тот, кто владеет ресурсом.
Фабрика же отдает ресурс во владение, значит и освобождать вам.
1
19491 / 10097 / 2460
Регистрация: 30.01.2014
Сообщений: 17,805
17.07.2015, 09:12
Цитата Сообщение от просто_спросить Посмотреть сообщение
программа будет вызывать open(...) для обычных указателей,
Для этого надо сделать, чтобы open сразу возвращала умный указатель. Тогда подобное использование будет затруднено.
Цитата Сообщение от просто_спросить Посмотреть сообщение
и все-таки навязывать использование умных указателей изза такой пустяковой проблемы кажется как-то недемократично
Это нормально. Интерфейс (в широком смысле) должен навязывать правильное использование и ограничивать неправильное. Желательно это делать как можно раньше, в идеале на этапе компиляции.
Цитата Сообщение от просто_спросить Посмотреть сообщение
неужели все так серьезно?
Корректная работа с ресурсами - это всегда серьезно.
Цитата Сообщение от просто_спросить Посмотреть сообщение
а как же правило "кто память выделяет,тот и освобождает"?
А оно тут не нарушается. Не нужно его настолько буквально понимать. В случае с умным указателем (теперь внимательно) метод open сам задает стратегию освобождения ресурса, который он выделил. Т.е., возвращаемое методом open значение, содержит в себе информацию о том, как правильно свободить ресурс. Это и есть практическая реализация этого правила. И получается, что не смотря на то, что физически освобождения ресурса будет в другом контексте, стратегию освобождения назначил именно тот, кто ресурс выделил. Это решение является наилучшим, по той причине, что закрепляет это правило не только на словах, к в случае твоих примеров (т.е., например у тебя delete осуществляется функцией из того же класса, что ресурс выделил, но забота об этом все равно ложится на пользователя, что дает право на ошибку), но и на уровне контракта, сильно мешая попыткам забыть освободить ресурс или освободить его не предназначающейся для этого функцией (например вместо delete позвать std::free), а также дает гарантии безопасности исключений.
Также рекомендую ознакомиться с основной идиомой С++ - RAII, на базе которой строится концепция умных указателей.

Очень рекомендую к прочтению книги
Стандарты программирования на C++, Г. Саттер и А. Александреску.
Эффективное использование С++ (55 советов), С. Мэйерс
Сложные задачи на С++ и Новые сложные задачи на С++, Г. Саттер

Начать можно с первой книги. Обозначенная в теме проблема, рассматривается в правиле 13.

Цитата Сообщение от просто_спросить Посмотреть сообщение
только не снизит ли это производительность?
Вариант с unique_ptr не снизит вообще.
Почитать про различные умные указатели и их отличия можно здесь. К сожалению статья не учитывает последний стандарт С++ (т.к. на тот момент он еще не вышел), но концептуально ничего не изменилось, т.ч. это не страшно.

Цитата Сообщение от просто_спросить Посмотреть сообщение
а среди вышепредложенных вариантов вообще ни одного корректного нет?
Вариант с delete this вообще используется в определенных ситуациях, но в твоем случае он выглядит надуманным.
2
17.07.2015, 10:37

Не по теме:

Цитата Сообщение от DrOffset Посмотреть сообщение
Вариант с unique_ptr не снизит вообще.
При условии отсутствия кастомного делитера конечно.
Цитата Сообщение от DrOffset Посмотреть сообщение
статья не учитывает последний стандарт С++
А так же и предпоследний. Всё-таки на сегодня последний это C++14 уже.

0
17.07.2015, 10:43

Не по теме:

Цитата Сообщение от Tulosba Посмотреть сообщение
А так же и предпоследний. Всё-таки на сегодня последний это C++14 уже.
Да, но насколько мне известно, в отношении умных указателей там ничего не поменялось особо.
Цитата Сообщение от Tulosba Посмотреть сообщение
При условии отсутствия кастомного делитера конечно.
Если кастомный заинлайнится, то тоже не будет.
Там же он идет как часть типа. аргументом шаблона. т.е. навязанной косвенности нет (я имею в виду, если бы делитер хранился как указатель на функцию, например), и если будет возможность inline, то это будет сделано. :)

0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
17.07.2015, 11:30
Цитата Сообщение от Cra3y Посмотреть сообщение
Освобождать должен тот, кто владеет ресурсом.
Фабрика же отдает ресурс во владение, значит и освобождать вам.
рецепт, как изготовить сишный говнокод?

Цитата Сообщение от просто_спросить Посмотреть сообщение
по-хорошему память должен освобождать тот, кто выделил
совершенно верно.
в случае со смартами это выглядит так:

http://rextester.com/XPQ32381

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
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
#include <iostream>
#include <string>
#include <memory>
 
struct IImage
{
    //virtual ~IImage(){}
    
    
    // обратите внимание: диструктор базового класса не виртуальный
    // в обычной жизни это может привести к UB 
    // (потерям ресурсов, утечкам памяти, крашам, и тп)
    
    // но в нашем случае, тем не менее все отработает, как часики
    // скажем спасибо смартпоинтерам
    ~IImage(){}
    
    virtual const char* AboutMe()const = 0;
};
 
 
struct Png: IImage
{
    Png(){ std::cout<<"Png was created\n"; }
    
    ~Png() { std::cout<<"Png was destroyed\n"; }
    
    virtual const char* AboutMe()const  { return "PNG"; }
};
 
 
struct Custom: IImage
{
    Custom(){ std::cout<<"Custom was created\n"; }
    
    ~Custom() { std::cout<<"Custom was destroyed\n"; }
    
    virtual const char* AboutMe()const  { return "Custom"; }
};
    
 
struct FactoryImage
{
    typedef std::shared_ptr<IImage>
        Image;
    
    static Image Load(const char* filename)
    {
        const std::string file = filename;
        
        if(file.find(".png")!=std::string::npos)
           return std::make_shared<Png>();
        
        return std::make_shared<Custom>();
    }
};
 
 
 
int main()
{
    std::cout << "Hello, world!\n";
    
    // обратите внимание:
    // вызывающая сторона сама лично не захватывала ресурсы
    // и поэтому не несет отвественность за их освобождение
    
    // грузим png
    const auto bitmap1 = FactoryImage::Load("example.png");
    std::cout<<"resource = "<< bitmap1->AboutMe() << std::endl;
    
    // грузим custom
    const auto bitmap2 = FactoryImage::Load("example.custom");
    std::cout<<"resource = "<< bitmap2->AboutMe() << std::endl;
    
    
    // тем не менее, все ресурсы будут корректно освобождены
    // за это отвечает тот, кто их выделял - фабрика
    // она сама подготавливает "правильные" смарты
    // которые позаботся о корректном освобождении.
    
    // после этой надписи наша программа завершается
    // и мы должны увидеть запуски диструкторов
    // всех захваченных фабрикой ресурсов
    std::cout<<"[Work completed] expect to release all resources...\n";
    
    // таким образом реализуется правило "кто ресурс захватывал, тот его и освобождает"
        
}
4
:)
Эксперт С++
4773 / 3267 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
17.07.2015, 12:01
Цитата Сообщение от hoggy Посмотреть сообщение
в случае со смартами это выглядит так:
Это потому что у тебя общее владение (shared_ptr), а не эксклюзивное (unique_ptr).
При этом освобождение осуществляет не тот кто создавал, а последний, кто использует.
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
17.07.2015, 14:17
Цитата Сообщение от Tulosba Посмотреть сообщение
Это потому что у тебя общее владение (shared_ptr), а не эксклюзивное (unique_ptr).
это не принципиально.

Цитата Сообщение от Tulosba Посмотреть сообщение
При этом освобождение осуществляет не тот кто создавал, а последний, кто использует.
это техническая сторона самого смартпоинтера.
но в данном случае, это так же не принципиально.

потому что, это никак не мешает фабрике
(менеджеру, ядру системы, тому, кто выдает интерфейс управления ресурсом)
монопольно контролировать время жизни ресурсов.

мы легко можем:
1. полностью запретить уничтожение ресурса вызывающей стороной.

2. в случае, если снаружи ресурс больше не нужен,
то мы можем не уничтожать его, а просто отложить в сторонку с пометкой "ресурс своден".

3. продливать жизнь ресурса, когда на него больше не ссылается ни один потребитель.

допустим, в этот самый момент времени в системном потоке идет обработка всех ресурсов ядра.
в этот момент нельзя физически уничтожать ресурсы.

тогда в случае, когда последний внешний потребитель отказывается от ресурса,
система автоматически получает сигнал:
"ресурс больше никому не нужен",
он помечается как "свободный".
конвейер его пропустит.
а по завершению работы конвейера можно либо удалить ненужный ресурс, либо см пункт 2.

в общем, все зависит от потребностей задачи.

а суть простая:
внешняя сторона имеет доступ к интерфейсу (функционалу) ресурса,
но она им не владеет: не контролирует время его жизни.

что бы было понятнее, проиллюстрирую этот момент:

http://rextester.com/UWJJU90090

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
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
#include <iostream>
#include <cassert>
#include <string>
#include <memory>
#include <map>
 
//--- интерфейс ресурса
struct IImage
{
    virtual ~IImage(){}
    virtual const char* AboutMe()const = 0;
};
 
// --- ресурс
struct Png: IImage
{
    Png() { std::cout<<"Png was created\n";   }
   ~Png() { 
std::cout<<"Png was destroyed\n"; 
}
    virtual const char* AboutMe()const { return "PNG"; }
};
 
// --- ресурс
struct Custom: IImage
{
    Custom() { std::cout << "Custom was created\n";   }
   ~Custom() { std::cout << "Custom was destroyed\n"; }
    virtual const char* AboutMe()const { return "Custom"; }
};
    
// --- ядро системы, контролирует ресурсы
struct Core
{
    typedef std::shared_ptr<IImage>
        Image;
    
    // --- подсистемы обычно - сингелтоны
    // данный метод не оч красиво оформлен
    // но для данной иллюстрации сойдет
    static Image Load(const char* filename)
    {
        static Core c;
        return c.CreateResource(filename);
    }
private:    
    typedef std::shared_ptr<IImage>
        Res;
    typedef std::map<Res, bool>    
        Resources;
 
    ~Core()
    {
        // --- при уничтожении системы, 
        // она сама позаботится о своих оставшихся ресурсах
        // и никто, кроме неё не знает, 
        // как это правильно сделать.
        // и вообще, не должен об этом думать
        std::cout<<"[SYSTEM] list resources:\n";
        for(const auto& i: mResources)
            std::cout
                << " [RESOURCE] " << i.first->AboutMe()
                << " : status = " << (i.second? "enabled\n" : "disabled\n");
 
        std::cout<<"[SYSTEM] deactivate...\n";
    }
    
    Image CreateResource(const char* filename)
    {
        // --- обратите внимание:
        // смарт, который получает вызывающая сторона 
        // не контролирует время жизни ресурса
        // пользователю будет доступен интерфейс ресурса
        // но он никак не сможет уничтожить сам ресурс 
        // в обход системы, которая на самом деле
        // является единственным (монопольным) 
        // владельцем ресурса.
 
        // когда снаружи у смартов не останется потребителей
        // то последний оставшийся в живых просигналит системе
        // о том, что ресурс снаружи больше никому не нужен
        // дальнейшая судьба ресурса полностью на усмотрение самой системы
        // в данном примере-иллюстрации система не будет уничтожать ресурсы
        // а будет лишь помечать их как "освободившиеся".
 
        // функтор будет запущен внешними смартами,
        // когда у ресурса не останется потребителей
        // запуск функтора будет сигналом о том, 
        // что ресурс можно освободить
        const auto deletter 
            =  [this](IImage* res){ Free(res); };
 
        // физически ресурс живет в потрохах системы
        // и не допступен снаружи
        const auto pair_ 
            = mResources.emplace(std::move(Make(filename)), true);
 
        const auto& res 
            = pair_.first->first;
        
        std::cout<<"[SYSTEM] create resource: '" 
            << res->AboutMe() <<"'\n";
 
        // выдаваемый наружу смарт может лишь 
        // предоставить доступ к интерфейсу ресурса
        // но не контролирует время жизни самого ресурса
        // он лишь просигналит системе о том, 
        // что у ресурса больше нет потребителей
        return Image(res.get(), deletter);
    }
 
    // захват реального ресурса.
    // приватный метод, только для служебного пользования
    static Res Make(const char* filename)
    {
        const std::string file = filename;
        if(file.find(".png") != std::string::npos)
            return Res(new Png); 
 
        return Res(new Custom); 
    }
    
    // только для служебного пользования
    // когда смарт снаружи просигналит об отсутствии потребителей
    // запуститься этот метод
    void Free(IImage* res)
    {
        std::cout
            << "[SYSTEM] detected free resource: '"
            << res->AboutMe()<<"'\n";
        
        // здесь мы можем сделать с ресурсом все, что захотим.
        // можем убить его. или переиспользовать.
        // зависит от задачи и от фантазии.
 
        // в данном примере, 
        // ресурс просто помечается как "не занятый".
        Res key(res, [](IImage*){});
        auto it = mResources.find(key);
        assert(it!=mResources.end());
        it->second = false;
    }
    
    Resources mResources;
    
};
 
 
 
int main()
{
    std::cout << "Hello, world!\n";
    
    
    // грузим png
    const auto bitmap1 = Core::Load("example.png");
    std::cout<<"resource = "<< bitmap1->AboutMe() << std::endl;
    
    // грузим custom
    const auto bitmap2 = Core::Load("example.custom");
    std::cout<<"resource = "<< bitmap2->AboutMe() << std::endl;
    
    std::cout<<"[Work completed] expect to release all resources...\n";
    
}

резюмируя: смарт-поинтеры - это больше чем просто способ контроля за утечками памяти.

это - мощный паттерн,
позволяющий детально контролировать время жизни и права доступа ресурсов.

и если в каком то отдельно взятом случае,
через смарт можно грохнуть ресурс - то это лишь по той причине,
что большего и не требуется.

однако, с точки зрения архитектуры,
владеет и контролирует время жизни ресурса именно тот, кто его создавал.

а не "механизм shared_ptr, который держит указатель на аллоцированный объект".

shared_ptr - всего лишь пешка в этой игре,
чьими руками предоставляется доступ к ресурсу.
12
0 / 0 / 0
Регистрация: 16.07.2015
Сообщений: 7
17.07.2015, 15:27  [ТС]
почитал, погуглил, посмотрел книги (захватывает, будем читать) и вроде по большей части рекомендуется использовать умные указатели.
а если использовать shared_ptr, счетчик ссылок может существенно снизить производительность при использовании в нескольких потоках?
и все-таки раньше, в C++98, как-то все без умных указателей решалось?
Цитата Сообщение от hoggy Посмотреть сообщение
продливать жизнь ресурса, когда на него больше не ссылается ни один потребитель
но зачем?

Не по теме:

qt creator 3.3 не поддерживает автоподстановку для умных указателей. неудобно блин. это везде так или с qt creator'а придется слезть?

0
В астрале
Эксперт С++
 Аватар для ForEveR
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
17.07.2015, 15:34
просто_спросить, Я дико подозреваю, что использовали либо boost, либо другие сторонние библиотеки, либо писали свои smart pointers, либо пользовались обычными указателями, но в основном все же, полагаю сторонние либы.
2
:)
Эксперт С++
4773 / 3267 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
17.07.2015, 15:49
Цитата Сообщение от просто_спросить Посмотреть сообщение
qt creator 3.3 не поддерживает автоподстановку для умных указателей.
Не знаю, как на 3.3, но на 3.4.2. никаких проблем с этим нет. Собственно и раньше не замечал.
2
Диванный эксперт
Эксперт С++
 Аватар для Max Dark
2550 / 2064 / 971
Регистрация: 09.10.2013
Сообщений: 4,793
Записей в блоге: 4
17.07.2015, 15:59
Цитата Сообщение от просто_спросить Посмотреть сообщение
qt creator 3.3 не поддерживает автоподстановку для умных указателей. неудобно блин. это везде так или с qt creator'а придется слезть?
Попробуйте включить ClangCodeModel в меню Справка->"О модулях"
2
0 / 0 / 0
Регистрация: 16.07.2015
Сообщений: 7
17.07.2015, 17:28  [ТС]
Цитата Сообщение от Cra3y Посмотреть сообщение
Попробуйте включить ClangCodeModel
обновил creator, включил ClangCodeModel, почему-то не работает автоподстановка именно с unique_ptr, с другими типами все отлично. хоть свой unique_ptr пиши.
всем огромное спасибо за ответы! поставили меня на путь истины. оказывается никакой магии в умных указателях нет, все прозрачно. только вот что.
C++
1
2
shared_ptr< Bitmap > bmp1 = shared_ptr< Bitmap >(new Bitmap());
shared_ptr< Bitmap > bmp2 = make_shared< Bitmap >(); // на некоторых ресурсах пишут что так быстрее и безопаснее (интересно как это реализовано)
если второй способ "лучше" на кой нужен первый? или он просто раньше появился?
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
17.07.2015, 17:36
Цитата Сообщение от просто_спросить Посмотреть сообщение
но зачем?
я специально раскрыл момент 3й пункта:

допустим, в этот самый момент времени в системном потоке идет обработка всех ресурсов ядра.
в этот момент нельзя физически уничтожать ресурсы.

тогда в случае, когда последний внешний потребитель отказывается от ресурса,
система автоматически получает сигнал:
"ресурс больше никому не нужен",
он помечается как "свободный".
конвейер его пропустит.
а по завершению работы конвейера можно либо удалить ненужный ресурс, либо см пункт 2.

в общем, все зависит от потребностей задачи.
если после прочтения этого абзаца вам не понятно,
зачем может быть нужной возможность продливать жизнь ресурсам,
значит не стоит и переживать по этому поводу.

вы просто имеете ввиду: технически это возможно.

вы все поймете позже,
когда в будущем столкнетесь с задачами,
где это окажется необходимым.
2
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
17.07.2015, 17:36
Помогаю со студенческими работами здесь

С++ Проверка освобождения памяти
Добрый день. На начальном курсе С++ получил такую задачу: Написать функцию, которая получает массив строк и его размер, и...

Указатель после освобождения памяти
Стивен Прата, глава 4, раздел &quot;Освобождение памяти с помощью операции delete&quot; Я пытаюсь понять. Написал: #include...

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

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

Ошибка освобождения памяти new/delete
При выполнении оператора deleterez вылетает ошибка BLOCK_TYPE_IS_VALID(pHead-&gt;nBlockUse) #include &lt;iostream&gt; using...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Access
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
Фото: Daniel Greenwood
kumehtar 13.11.2025
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru