Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.50/6: Рейтинг темы: голосов - 6, средняя оценка - 4.50
58 / 62 / 34
Регистрация: 14.03.2014
Сообщений: 933

Утечка памяти

12.08.2020, 13:46. Показов 1205. Ответов 19
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Не могу понять почему происходит утечка.
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
#pragma once
namespace sdds
{
    struct Fruit
    {
        char m_name[31]; // the name of the fruit
        double m_qty;        // quantity in kilograms
    };
 
    class Basket {
        static int num; // 
        Fruit *m_fruit;
        int m_cnt;
        double m_price;
 
    public:
        Basket();
        Basket(Fruit*, int, double);
        void setPrice(double price);
        void safeEmptyStateBasket();
        Basket(const Basket &);
        Basket& operator=(const Basket&);
        ~Basket();
        Basket& operator+=(const Fruit);
        friend std::ostream & operator<<(std::ostream& os, const Basket& b);
        operator bool() const;
    };
 
}
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
#include <iostream>
#include "Basket.h"
using namespace std;
 
namespace sdds {
    int Basket::num = 0;
 
    void Basket::safeEmptyStateBasket() {
        m_fruit = nullptr;
        m_cnt = 0;
        m_price = 0.0;
    }
 
    Basket::Basket() {
        num++;
        cout << "<<<<Created new object>>>> " << num << endl;
        safeEmptyStateBasket();
 
    }
 
    Basket::Basket(Fruit* fruit, int cnt, double price)
    {
        num++;
        cout << "<<<<Created new object>>>> " << num << endl;
        if (fruit != nullptr && cnt > 0)
        {
            m_fruit = new Fruit[cnt];
            for (int i = 0; i < cnt; i++)
                m_fruit[i] = fruit[i];
            m_cnt = cnt;
            m_price = price;
        }
 
        else
            safeEmptyStateBasket();
    }
 
    void Basket::setPrice(double price) {
        m_price = price;
    }
 
    Basket::Basket(const Basket &st)
    {
        num++;
        cout << "<<<<Created new object>>>> " << num << endl;
        if (st.m_fruit != nullptr && st.m_cnt > 0)
        {
            //delete[] m_fruit;
            m_cnt = st.m_cnt;
            m_fruit = new Fruit[m_cnt];
            for (int i = 0; i < m_cnt; i++)
                m_fruit[i] = st.m_fruit[i];
            m_price = st.m_price;
        }
 
        else
            safeEmptyStateBasket();
    }
 
    Basket& Basket::operator=(const Basket& st) {
        
        if (st.m_fruit != nullptr && st.m_cnt > 0)
        {
            delete[] m_fruit;
            m_cnt = st.m_cnt;
            m_fruit = new Fruit[m_cnt];
            for (int i = 0; i < m_cnt; i++)
                m_fruit[i] = st.m_fruit[i];
            m_price = st.m_price;
        }
 
        else
            safeEmptyStateBasket();
 
        return *this;
    }
 
    Basket::~Basket() {
        cout << "<<<<Delete object>>>> " << num << endl;
        num--;
        delete[]m_fruit;
    }
 
    Basket& Basket::operator+=(const Fruit st) {
 
        Fruit* temp = new Fruit[m_cnt + 1];
        for (int i = 0; i < m_cnt; i++)
            temp[i] = m_fruit[i];
        temp[m_cnt] = st;
        m_cnt++;
 
        Fruit* tmp = m_fruit;
        m_fruit = temp;
        temp = tmp;
 
        delete[] temp;
        return *this;
    }
 
    std::ostream & operator<<(std::ostream& os, const Basket& b)
    {
        if (b.m_fruit == nullptr)
            os << "The basket is empty!\n";
        else
        {
            os << "Basket Content:\n";
            os.setf(ios::fixed);
            os.precision(2);
            os << fixed;
            for (int i = 0; i < b.m_cnt; i++)
                os << "\t" << b.m_fruit[i].m_name << ": "<< b.m_fruit[i].m_qty << "kg\n";
            os << "Price: " << b.m_price << endl;
        }
        return os;
    }
 
    Basket::operator bool() const
    {
        if (m_cnt > 0)
            return true;
        return false;
    }
}
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
#define __CRTDBG_MAP_ALLOC
#include <crtdbg.h>
#define DEBUG_NEW new(_NORMAL_BLOCK, __FILE__, __LINE__)
#define new DEBUG_NEW
 
#include<iostream>
#include<cstring>
#include"Basket.h"
#include"Basket.h" //intentional
 
using namespace std;
using namespace sdds;
 
void printHeader(const char* title)
{
    char oldFill = cout.fill('-');
    cout.width(40);
    cout << "" << endl;
 
    cout << "|> " << title << endl;
 
    cout.fill('-');
    cout.width(40);
    cout << "" << endl;
    cout.fill(oldFill);
}
 
int main()
{
    sdds::Fruit fruits[]{
        { "apple",  0.65 },
        { "banana", 1.25 },
        { "pear",   0.50 },
        { "mango",  0.75 },
        { "plum",   2.00 },
    };
 
    {
        printHeader("T1: Default Constructor");
 
        Basket aBasket;
        cout << aBasket;
 
        // conversion to bool operator
        if (aBasket)
            cout << "Test failed: the basket should be empty!\n";
        else
            cout << "Test succeeded: operator said the basket is empty!\n";
 
        cout << endl;
    }
 
    {
        printHeader("T2: Custom Constructor");
 
        Basket aBasket(fruits, 2, 6.99);
        cout << aBasket;
 
        // conversion to bool operator
        if (aBasket)
            cout << "Test succeeded: operator said the basket has content!\n";
        else
            cout << "Test failed: the basket should NOT be empty!\n";
 
        cout << endl;
    }
 
    {
        printHeader("T3: += operator");
 
        Basket aBasket;
        aBasket += fruits[2];
        (aBasket += fruits[0]) += fruits[4];
        aBasket.setPrice(12.234);
 
        cout << aBasket;
        cout << endl;
    }
 
    {
        printHeader("T4: Copy Constructor");
 
        Basket b1;
        Basket b2(b1);
 
        cout << "Basket #1 -> " << b1;
        cout << "Basket #2 -> " << b2;
 
        b1 += fruits[3];
        b1.setPrice(3.50);
 
        Basket b3(b1);
        cout << "Basket #3 -> " << b3;
        cout << endl;
    }
 
    {
        printHeader("T5: Copy Assignment");
 
        Basket b1, b2, b3(fruits, 5, 19.95);
 
        b1 = b2;
        cout << "Basket #1 -> " << b1;
        cout << "Basket #2 -> " << b2;
 
        b1 = b3;
        cout << "Basket #1 -> " << b1;
 
        b3 = b2;
        cout << "Basket #3 -> " << b3; 
    }
 
    system("pause");
    _CrtDumpMemoryLeaks();
    return 0;
}
Это происходит тут:
C++
1
b3 = b2;
Detected memory leaks!
Dumping objects ->
{251} normal block at 0x013EEFC0, 200 bytes long.
Data: <apple > 61 70 70 6C 65 00 00 00 00 00 00 00 00 00 00 00
Object dump complete.
По какой причине?
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
12.08.2020, 13:46
Ответы с готовыми решениями:

Утечка памяти
Доброго времени суток, форумчане. Помогите справиться с утечкой памяти, не понятно где зараза засела. Это класс представления числа в СОК...

Утечка памяти
Првиетствую, помогите пожалуйста! Делаю бота для игры в вк. Но с каждым проходом внешнего цикла память утекает на 500мб (я думаю это...

Утечка памяти?!
Джесс Либерти и Дэвид Хорват &quot;Освой самостоятельно С++ за 24 часа&quot;, вырезка из листинга 15.4 (стр 233): Строка 26 - Утечка памяти?...

19
19491 / 10097 / 2460
Регистрация: 30.01.2014
Сообщений: 17,805
12.08.2020, 14:23
Senarist, а если так:
Кликните здесь для просмотра всего текста
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
int main()
{
 {  
    sdds::Fruit fruits[]{
        { "apple",  0.65 },
        { "banana", 1.25 },
        { "pear",   0.50 },
        { "mango",  0.75 },
        { "plum",   2.00 },
    };
 
    {
        printHeader("T1: Default Constructor");
 
        Basket aBasket;
        cout << aBasket;
 
        // conversion to bool operator
        if (aBasket)
            cout << "Test failed: the basket should be empty!\n";
        else
            cout << "Test succeeded: operator said the basket is empty!\n";
 
        cout << endl;
    }
 
    {
        printHeader("T2: Custom Constructor");
 
        Basket aBasket(fruits, 2, 6.99);
        cout << aBasket;
 
        // conversion to bool operator
        if (aBasket)
            cout << "Test succeeded: operator said the basket has content!\n";
        else
            cout << "Test failed: the basket should NOT be empty!\n";
 
        cout << endl;
    }
 
    {
        printHeader("T3: += operator");
 
        Basket aBasket;
        aBasket += fruits[2];
        (aBasket += fruits[0]) += fruits[4];
        aBasket.setPrice(12.234);
 
        cout << aBasket;
        cout << endl;
    }
 
    {
        printHeader("T4: Copy Constructor");
 
        Basket b1;
        Basket b2(b1);
 
        cout << "Basket #1 -> " << b1;
        cout << "Basket #2 -> " << b2;
 
        b1 += fruits[3];
        b1.setPrice(3.50);
 
        Basket b3(b1);
        cout << "Basket #3 -> " << b3;
        cout << endl;
    }
 
    {
        printHeader("T5: Copy Assignment");
 
        Basket b1, b2, b3(fruits, 5, 19.95);
 
        b1 = b2;
        cout << "Basket #1 -> " << b1;
        cout << "Basket #2 -> " << b2;
 
        b1 = b3;
        cout << "Basket #1 -> " << b1;
 
        b3 = b2;
        cout << "Basket #3 -> " << b3; 
    }
 }
    system("pause");
    _CrtDumpMemoryLeaks();
    return 0;
}

?
0
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
12.08.2020, 14:26
Цитата Сообщение от Senarist Посмотреть сообщение
Не могу понять почему происходит утечка.
Цитата Сообщение от Senarist Посмотреть сообщение
Basket& Basket::operator=(const Basket& st) {
if (st.m_fruit != nullptr && st.m_cnt > 0)
        {
            delete[] m_fruit;
Если t пустой, то старое содержимое не удаляется
1
58 / 62 / 34
Регистрация: 14.03.2014
Сообщений: 933
12.08.2020, 14:27  [ТС]
DrOffset, Ага, пробовал, тоже самое(
0
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
12.08.2020, 14:27
Утечка вот здесь
Цитата Сообщение от Senarist Посмотреть сообщение
b3 = b2;
        cout << "Basket #3 -> " << b3;
0
58 / 62 / 34
Регистрация: 14.03.2014
Сообщений: 933
12.08.2020, 14:33  [ТС]
oleg-m1973, А да, забыл про это. Поправил это так:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
Basket& Basket::operator=(const Basket& st) {
        
        if (st.m_fruit != nullptr && st.m_cnt > 0)
        {
            if (this == &st)
                return *this;
            delete[] m_fruit;
            m_cnt = st.m_cnt;
            m_fruit = new Fruit[m_cnt];
            for (int i = 0; i < m_cnt; i++)
                m_fruit[i] = st.m_fruit[i];
            m_price = st.m_price;
        }
 
        else
        {
            delete[] m_fruit;
            safeEmptyStateBasket();
        }
 
        return *this;
    }
правда как то не очень красиво. Но утечки теперь нет
0
12.08.2020, 14:35

Не по теме:

Цитата Сообщение от Senarist Посмотреть сообщение
правда как то не очень красиво.
но лучше чем в хедерах stl

0
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
12.08.2020, 14:35
Цитата Сообщение от Senarist Посмотреть сообщение
правда как то не очень красиво. Но утечки теперь нет
Сделай для своего класса метод swap. Тогда
C++
1
2
3
4
5
6
Basket& Basket::operator=(const Basket& st) 
{
    if (this != &st)
        Basket(st).swap(*this);
    return *this;
}
1
58 / 62 / 34
Регистрация: 14.03.2014
Сообщений: 933
12.08.2020, 14:51  [ТС]
oleg-m1973, Ок
Хотя это будет сбивать с толку. swap имеется в виду обмен, а тут присваивание в одну сторону)
0
19491 / 10097 / 2460
Регистрация: 30.01.2014
Сообщений: 17,805
12.08.2020, 15:12
Senarist, это идиома copy-and-swap, никого она с толку не сбивает
2
58 / 62 / 34
Регистрация: 14.03.2014
Сообщений: 933
12.08.2020, 15:15  [ТС]
Цитата Сообщение от DrOffset Посмотреть сообщение
это идиома copy-and-swap, никого она с толку не сбивает
Спасибо, не знал про это
0
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
12.08.2020, 15:44
Цитата Сообщение от Senarist Посмотреть сообщение
Хотя это будет сбивать с толку. swap имеется в виду обмен, а тут присваивание в одну сторону)
Ну, твоя реализация гораздо сильнее сбивает с толку. Например вот этот финт ушами
Цитата Сообщение от Senarist Посмотреть сообщение
Fruit* tmp = m_fruit;
        m_fruit = temp;
        temp = tmp;
delete[] temp;
        return *this;
Однако, тебя это не смущает
0
 Аватар для Annemesski
2670 / 1333 / 479
Регистрация: 08.11.2016
Сообщений: 3,679
12.08.2020, 15:51
Цитата Сообщение от oleg-m1973 Посмотреть сообщение
C++
1
2
3
4
5
Fruit* tmp = m_fruit;
 m_fruit = temp;
 temp = tmp;
delete[] temp;
 return *this;
Я секунд на 15 завис, пока не понял что tmp и temp - это не одно и тоже имя )))
0
58 / 62 / 34
Регистрация: 14.03.2014
Сообщений: 933
12.08.2020, 15:53  [ТС]
Цитата Сообщение от Annemesski Посмотреть сообщение
Я секунд на 15 завис, пока не понял что tmp и temp - это не одно и тоже имя )))
Ну проблема у меня с придумыванием наименований
0
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
12.08.2020, 15:55
Цитата Сообщение от Senarist Посмотреть сообщение
Ну проблема у меня с придумыванием наименований
Здесь не в именах проблема (хотя и в них тоже). Вместо этого здесь должно быть
C++
1
2
3
    delete[] m_fruit ;
        m_fruit = temp;
        return *this;
1
58 / 62 / 34
Регистрация: 14.03.2014
Сообщений: 933
12.08.2020, 15:56  [ТС]
Цитата Сообщение от oleg-m1973 Посмотреть сообщение
Однако, тебя это не смущает
ну а как еще то. Сейчас появился swap, теперь для этого момента писать swap1 ?
0
262 / 151 / 33
Регистрация: 29.06.2019
Сообщений: 1,515
14.08.2020, 08:35
Цитата Сообщение от DrOffset Посмотреть сообщение
это идиома copy-and-swap, никого она с толку не сбивает
генерация исключения могла бы привести к утечке памяти.
значит вот что может привести к утечке памяти... а я думала, что только я сама могу привести к утечке памяти (неправильными new-delete)
спасибо
0
19491 / 10097 / 2460
Регистрация: 30.01.2014
Сообщений: 17,805
14.08.2020, 08:38
Цитата Сообщение от JeyCi Посмотреть сообщение
значит вот что может привести к утечке памяти... а я думала, что только я сама могу привести к утечке памяти
Это тоже будет "вы сами".
Исключение - это еще одна, дополнительная ветка передачи управления. В ней тоже должен быть предусмотрен способ освободить ресурсы. Стандартным способом для С++, чтобы это сделать, являются деструкторы.
А дальше вступают в ход всякие техники, которые позволяют правильно эти деструкторы использовать в контексте с исключениями.
1
58 / 62 / 34
Регистрация: 14.03.2014
Сообщений: 933
14.08.2020, 08:55  [ТС]
Цитата Сообщение от oleg-m1973 Посмотреть сообщение
Вместо этого здесь должно быть

   
C++
1
2
3
delete[] m_fruit ;
        m_fruit = temp;
        return *this;
Цитата Сообщение от oleg-m1973 Посмотреть сообщение
Здесь не в именах проблема (хотя и в них тоже). Вместо этого здесь должно быть
Спс! Не знаю поч я до этого не написал так, видимо о чем то другом думал
0
262 / 151 / 33
Регистрация: 29.06.2019
Сообщений: 1,515
14.08.2020, 11:58
Цитата Сообщение от DrOffset Посмотреть сообщение
В ней тоже должен быть предусмотрен способ освободить ресурсы.
вобщем, как обычно, насколько понимаю... если создаём объекты с помощью new, то надо ограничить зону видимости delete'ом... если зона видимости для объекта ограничена, то при выходе из неё объект будет уничтожен сам - независимо от того, нормальный выход или с исключением...
Цитата Сообщение от DrOffset Посмотреть сообщение
А дальше вступают в ход всякие техники, которые позволяют правильно эти деструкторы использовать в контексте с исключениями
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
14.08.2020, 11:58
Помогаю со студенческими работами здесь

Утечка памяти
Доброго времени суток! Столкнулся с проблемой утечки памяти! Будь у меня маленькая программка, выловил бы легко, но в 2000 строк кода все...

Утечка памяти
Здравствуйте. Есть программа (разбитая на функции) постоянно работающая в цикле и выводящая информацию на консоль. И получается что она...

Утечка памяти
Взял листинг кода из книги Стивен Прата Язык программирования С++. Меня терзают смутные сомнения нет ли здесь утечки памяти, указатель ...

Утечка памяти?
В Лафоре такой код: #include &lt;iostream&gt; using namespace std; /////////////////////////////////////////////////////////// class...

Утечка памяти
Господа подскажите как узнать какая п̶а̶д̶л̶а̶ переменная жрет память? Или как посмотреть сколько вообще переменных и объектов находятся в...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
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 . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru