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

delete[] *pointer vs. delete pointer и утечка памяти - C++

Восстановить пароль Регистрация
Другие темы раздела
C++ Название типа объекта typeid http://www.cyberforum.ru/cpp-beginners/thread950796.html
Когда вывожу название типа объекта, то перед ним появляются цифры 4 и 8. что они означают? В низу показал что выводит программа #include <iostream> #include <typeinfo> using namespace std; class Base {
C++ Тема: Структуры. Условие: сделать массив структур, который содержит следующею информацию В радиоателье сохраняются квитанции о заданной в ремонт аппаратуре. Каждая квитанция содержит такую информацию: название группы товаров(телевизоры, радиоприемники и т.д), марка товара, дата приема в ремонт, состояние готовности заказа(сделано, не сделано). Вывести информацию о состояние заказа на поточные сутки для заданной группы товаров. Наименование группы товаров ввести с клавиатуры. http://www.cyberforum.ru/cpp-beginners/thread950789.html
Проверка на расстановку скобок C++
В общем задание такое. Программа (консольная) проверяет каждую строку файла для проверки на расстановку скобок 4 типов ("(" и ")", "", "{" и "}", "<" и ">"), проверка должна учесть парность и вложенность расстановки скобок (как в математических выражениях), другие символы - пропускать без обработки. По результатам проверки формируется файл результатов, каждая строка которого соответствует...
Непонятен текст задания C++
Вот задание: b) Создать абстрактный тип данных (структура) - вектор, который имеет указатель на float и число элементов. Определить функции: инициализации, удаления вектора, установки/ изменения размера, доступа к элементам вектора, вычисления суммы элементов вектора. Для примера, в функции main, организовать поэлементное умножение двух векторов. Не понимаю на счет числа элементов Так как...
C++ Указатели (нужно передать массив в качестве параметра в функцию) http://www.cyberforum.ru/cpp-beginners/thread950771.html
Добрый день! имеется массив array его нужно передать в качестве параметра в функцию, принимающую в качестве аргумента LPVOID: function(LPVOID arr), я делаю так: function(&array), в большинстве случаев все работает, но иногда вылетает - пытаюсь понять, связано ли это с неправильной передачей аргумента, ?или все-таки нужно передавать function(array) без &, массив сам по себе это указатель на...
C++ В чем разница? Скажите в чем разница между двумя кусками кода: std::string a; while ((std::cin>>a)!="Quit") { std::cout<<a; } подробнее

Показать сообщение отдельно
Cynacyn
 Аватар для Cynacyn
33 / 33 / 0
Регистрация: 02.05.2013
Сообщений: 109
09.09.2013, 15:49     delete[] *pointer vs. delete pointer и утечка памяти
Здравствуйте!
Есть класс "умного" указателя counted_ptr, который удаляет хранящийся в нём T* owned; только если кол-во владельцев (хранящееся по адресу int* use_count), будет равно одному, иначе кол-во владельцев уменьшается на единицу.
counted_ptr владеет классом Pointer_pairs. Статический член
C++
1
 static vector<Pointer_pairs> vpp;
класса counted_ptr позволяет отслеживать состояние всех объектов counted_ptr.

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
// Ch 19. Ex 11. Realize counted_ptr 
//------------------------------------------------------------------------------
#include <vector>
#include <algorithm>
 
using std::vector;
//------------------------------------------------------------------------------
 
//------------------------------------------------------------------------------
template<class T>
class counted_ptr {
    T* owned;
    int* use_case;
 
    struct Pointer_pairs {
        void* arg_ptr;
        void* owned_ptr;
        int* number_of_owners;
    
        Pointer_pairs() 
            : arg_ptr(0),
              owned_ptr(0),
              number_of_owners(0)
        {}
        Pointer_pairs(void* arg, void* own, int* num) 
            : arg_ptr(arg),
              owned_ptr(own),
              number_of_owners(num)
        {}
        ~Pointer_pairs() {}
        // for sorting in reverse order. 
        // Pointer_pairs::number_of_owners==0 goes to the end
        // so we can pop_back() them from vpp
        bool operator<(const Pointer_pairs& p) {
            return (*number_of_owners)>*(p.number_of_owners);
        }
    };
 
    static vector<Pointer_pairs> vpp;
 
public:
 
    counted_ptr() : owned(0), use_case(0) { }
    counted_ptr(T* pt) : owned(0), use_case(0)
    {
        for(int i=0; i<vpp.size(); i++)
            if(pt==vpp[i].arg_ptr) {
                owned = static_cast<T*>(vpp[i].owned_ptr);
                ++(*vpp[i].number_of_owners);
                use_case=vpp[i].number_of_owners;
 
                cout << "couted_ptr(T* pt) " << this << "->" << " for " << owned << "->" << *owned << "[" << *use_case << "]" << endl;
 
                return;
            }
 
        if (pt) owned = new T(*pt);
        else owned = pt;
 
        vpp.push_back(Pointer_pairs(pt,owned,new int(1)));
        use_case = vpp[vpp.size()-1].number_of_owners;
        
        cout << "couted_ptr(T* pt) " << this << "->" << " for " << owned << "->" << *owned << "[" << *use_case << "]" << endl;
 
    }
    counted_ptr(const counted_ptr& cp) : owned(cp.owned), use_case(cp.use_case) 
    { 
        for(int i=0; i<vpp.size(); i++)
            if(cp.owned==vpp[i].owned_ptr) {
                ++(*vpp[i].number_of_owners);
                i = vpp.size();
            }
 
        cout << "couted_ptr(const counted_ptr& cp) " << this << "->" << " for " << owned << "->" << *owned << "[" << *use_case << "]" << endl;
    }
    counted_ptr& operator=(const counted_ptr& cp) 
    {
        if(this==&cp) return *this;
 
        // line 72: if this->(*use_case) == 1, it will delete owned from free store, preventing mem. leak
        counted_ptr temp(*this); 
 
        for(int i=0; i<vpp.size(); i++)
            if(owned==vpp[i].owned_ptr) {
                --(*vpp[i].number_of_owners);
                i = vpp.size();
            }
        
        for(int i=0; i<vpp.size(); i++)
            if(cp.owned==vpp[i].owned_ptr) {
                owned = cp.owned;
                ++(*vpp[i].number_of_owners);
                use_case = vpp[i].number_of_owners;
            }
 
        cout << "counted_ptr& operator=(const counted_ptr& cp) " << this << "->" << " for " << owned << "->" << *owned << "[" << *use_case << "]" << endl;
        return *this;
    }
    ~counted_ptr() {
        if(*use_case<2) {
            cout << "~couted_ptr() " << this << "->" << " for " << owned << "->" << *owned << "[" << *use_case << "]" << endl;
            for(int i=0; i<vpp.size(); i++) 
                if(owned==vpp[i].owned_ptr) {
                    *(vpp[i].number_of_owners)=-1;
                    i = vpp.size();
                }
            std::sort(vpp.begin(),vpp.end());
            vpp.pop_back();
            cout << "~couted_ptr() " << this << "->" << " for " << owned << "->" << *owned << "[" << *use_case << "]" << endl;
        //  delete [] owned;
            delete owned;
            delete use_case;
        }
        else {
            cout << "~couted_ptr() " << this << "->" << " for " << owned << "->" << *owned << "[" << *use_case << "]" << endl;
            for(int i=0; i<vpp.size(); i++) 
                if(owned==static_cast<T*>(vpp[i].owned_ptr)) {
                    --(*vpp[i].number_of_owners);
                    i = vpp.size();
                }
            }
    }
 
 
    
    int& owner_num() const {return *use_case; }
    
    T* release() {
        for(int i=0; i<vpp.size(); i++)
            if(owned==static_cast<T*>(vpp[i].owned_ptr)) {
                --vpp[i].number_of_owners;
                i = vpp.size();
                --(*use_case);
            }
    
        T* temp = owned;
        owned = 0;
        return temp;
    }
 
    T& operator*() {return *owned;}
    const T& operator*() const {return *owned;}
    T* operator->() { return owned; }
    const T* operator->() const {return owned; }
 
 
};
//------------------------------------------------------------------------------
template<class T>
vector<class counted_ptr<T>::Pointer_pairs> counted_ptr<T>::vpp;
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
Вот содержание main():
C++
1
2
3
4
5
6
7
8
9
    counted_ptr<string> cp(new string("FIRST"));
    //vector<counted_ptr<string>> vcps;
    //vcps.push_back(cp);
 
    counted_ptr<string> cp2(new string("SECOND"));
    cp = cp2;
 
    cout << cp.owner_num() << endl;
    cout << cp2.owner_num() << endl;
Если в counted_ptr.h поменять строки 110 на 111, т.е. вместо delete использовать delete[], то программа будет вылетать с debug assertion failed block type is valid phead nblockuse, но если в main() раскоментировать строки 2 и 3, то программа будет выдавать ожидаемый результат как с delete так и с delete[]. По условию задачи необходимо использовать опереатор new. Можно ли очистить память выделенную при помощи new не используя delete / delete[]?

Если пользователь инициализирует объект counted_ptr при помощи указателя на массив элементов, то delete удалит память занятую только первым элементом, при это произойдет утечка памяти, правильно?
Подскажите пожалуйста как избежать утечки памяти в данной ситуации?

Заранее, спасибо!
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
 
Текущее время: 12:21. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru