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

Ошибка при вызове деструктора

09.08.2018, 14:56. Показов 1342. Ответов 14
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте, помогите разобраться с проблемой, она довольно распространенная и на форуме куча сообщений про это но в моей программе я никак не могу найти где я ошибся, нужен ваш взгляд со стороны.
Вот код:
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
#include <cstring>
class vec
{
public:
    vec()
    {
        m_size = offset;
        m_len = 0;
        m_vector = new int[m_size];
        memset(m_vector, 0, sizeof(m_vector));
    }
    vec(size_t size)
    {
        m_size = size;
        m_len = 0;
        m_vector = new int[m_size];
        memset(m_vector, 0, sizeof(m_vector));
    }
    vec(const vec& orig)
        :
        m_size(orig.m_size),
        m_len(orig.m_len),
        m_vector(nullptr)
    {
        m_vector = new int[m_size];
        for (size_t i = 0; i < m_len; ++i)
        {
            m_vector[i] = orig.m_vector[i];
        }
    }
    ~vec()
    {
        if (m_vector != nullptr)
        {
            delete[] m_vector;
            m_vector = nullptr;
        }
    }
    size_t GetSize()
    {
        return m_size;
    }
    size_t GetLength()
    {
        return m_len;
    }
    int* GetValue()
    {
        return m_vector;
    }
    vec& operator= (const vec& rhs)
    {
        if (m_vector)
        {
            delete[] m_vector;
            m_vector = nullptr;
            m_len = rhs.m_len;
            m_vector = new int[m_size];
            for (size_t i = 0; i < m_len; ++i)
            {
                m_vector[i] = rhs.m_vector[i];
            }
        }
        return *this;
    }
    int& operator[] (size_t index)
    {
        return m_vector[index];
    }
    bool operator== (const vec& rhs)
    {
        if (m_len != rhs.m_len)
            return false;
        for (unsigned int i = 0; i < m_len; ++i)
        {
            if (m_vector[i] != rhs.m_vector[i])
                return false;
        }
        return true;
    }
    bool operator!= (const vec& rhs)
    {
        if (!(this == &rhs))
            return true;
        return false;
    }
    void push_back(int value)
    {
        if (m_len == m_size)
        {
            vec v = vec(m_size * (m_size / 2));
            v = *this;
            this->m_size = v.m_size;
            *this = v;
        }
        m_vector[m_len] = value;
        m_len++;
    }
    void erase(unsigned int pos)
    {
        m_vector[pos] = m_vector[m_len - 1];
    }
    void erase(unsigned int begin, unsigned int end)
    {
        for (unsigned int i = begin; i <= end; ++i)
        {
            m_vector[i] = m_vector[m_len - i - 1];
        }
    }
    void pop_back()
    {
        m_vector[m_len - 1] = 0;
    }
private:
    static constexpr size_t offset = 8;
    size_t m_size;
    size_t m_len;
    int* m_vector;
};
,

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
#include "Vec.h"
int main()
{
    vec v0;
    v0.push_back(2);
    v0.push_back(22);
    v0.push_back(234);
    v0.push_back(2325);
    printf("\n");
    for (unsigned int i = 0; i < v0.GetLength(); ++i)
    {
        printf("%d ", v0[i]);
    }
    vec v1(v0);
    v1.push_back(532);
    v1.push_back(2324);
    v1.push_back(1321);
    v1.push_back(6532);
    v1.push_back(42);
    printf("\n");
    for (unsigned int i = 0; i < v1.GetLength(); ++i)
    {
        printf("%d ", v1[i]);
    }
    vec v2;
    v2 = v1;
    v2.push_back(456);
    v2.push_back(452);
    v2.push_back(224);
    v2.push_back(12);
    v2.push_back(698);
    printf("\n");
    for (unsigned int i = 0; i < v2.GetLength(); ++i)
    {
        printf("%d ", v2[i]);
    }
    std::cin.get();
    return 0;
}
0
Лучшие ответы (1)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
09.08.2018, 14:56
Ответы с готовыми решениями:

Ошибка при вызове деструктора (при вызове delete в деструкторе)
Не могу найти ошибку, при вызове деструктора от класса, который был создан при помощи конструктора с параметром const String &amp;,...

Ошибка при вызове деструктора
По окончании программы выдает ошибку #include &lt;string.h&gt; #include &lt;iostream&gt; using namespace std; class nik //объявление...

Ошибка при вызове деструктора
Подскажите, что не так с этим деструктором? Просто выдает ошибку. Если его убираю то все идет норм. Если же оставляю, то куча всяких...

14
Форумчанин
Эксперт CЭксперт С++
 Аватар для MrGluck
8216 / 5047 / 1437
Регистрация: 29.11.2010
Сообщений: 13,453
09.08.2018, 15:23
Проверьте написание оператора присваивания
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
vec& operator= (const vec& rhs)
    {
        if (this != &rhs)
        {
            delete[] m_vector;
            m_len = rhs.m_len;
            m_size = rhs.m_size;
            m_vector = new int[m_size];
            for (size_t i = 0; i < m_len; ++i)
            {
                m_vector[i] = rhs.m_vector[i];
            }
        }
        return *this;
    }
Добавлено через 7 минут
А ещё выкиньте строки
C++
1
memset(m_vector, 0, sizeof(m_vector));
1. элементы в дин. массиве итак равны 0.
2. sizeof(m_vector) - размер указателя.
3. В С++ используют std::fill
1
0 / 0 / 0
Регистрация: 30.12.2015
Сообщений: 7
09.08.2018, 15:36  [ТС]
Внес предложенные вами изменения, не помогло.
Кстати почему Release версия не ругается? Я так понимаю очистка памяти возлагается на ОС?
0
 Аватар для QuakerRUS
1469 / 1010 / 456
Регистрация: 30.10.2017
Сообщений: 2,799
09.08.2018, 15:38
Лучший ответ Сообщение было отмечено Rastrizh как решение

Решение

Не забываем очищать массивы перед очисткой указателя.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
vec(const vec& orig)
        :
        m_size(orig.m_size),
        m_len(orig.m_len)
    {
        if (m_vector != nullptr)
            delete[] m_vector;
 
        m_vector = new int[m_size];
        for (size_t i = 0; i < m_len; ++i)
        {
            m_vector[i] = orig.m_vector[i];
        }
    }
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
vec& operator= (const vec& rhs)
    {
        if (m_vector != nullptr)
            delete[] m_vector;
    
        m_size = rhs.m_size;
        m_len = rhs.m_len;
        m_vector = new int[m_size];
        for (size_t i = 0; i < m_len; ++i)
        {
            m_vector[i] = rhs.m_vector[i];
        }
        return *this;
    }
Метод push_back у вас неправильно работает.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
void push_back(int value)
    {
        if (m_len == m_size)
        {
            m_size = m_size * (m_size / 2);
            int* temp_vector = m_vector;
            m_vector = new int[m_size];
            for (size_t i = 0; i < m_len; ++i)
            {
                m_vector[i] = temp_vector[i];
            }
            delete[] temp_vector;
        }
        m_vector[m_len] = value;
        m_len++;
    }
1
Модератор
Эксперт С++
 Аватар для zss
13771 / 10964 / 6491
Регистрация: 18.12.2011
Сообщений: 29,242
09.08.2018, 15:38
Цитата Сообщение от MrGluck Посмотреть сообщение
C++
1
2
3
4
5
m_vector = new int[m_size]; 
for (size_t i = 0; i < m_len; ++i);
{
   m_vector[i] = rhs.m_vector[i];
}
Выделяем память размером m_size
А заполняем m_len элементов.
Если m_len>m_size, то приплыли...
0
 Аватар для QuakerRUS
1469 / 1010 / 456
Регистрация: 30.10.2017
Сообщений: 2,799
09.08.2018, 15:43
Цитата Сообщение от zss Посмотреть сообщение
Если m_len>m_size, то приплыли...
По логике m_len не должна быть больше чем m_size. Вот только в методе push_back ошибка, из-за которой m_size не увеличивается корректно.
1
0 / 0 / 0
Регистрация: 30.12.2015
Сообщений: 7
09.08.2018, 15:57  [ТС]
QuakerRUS, я внес изменения которые вы предложили, и все равно вылазит ошибка
0
Неэпический
 Аватар для Croessmah
18146 / 10730 / 2066
Регистрация: 27.09.2012
Сообщений: 27,029
Записей в блоге: 1
09.08.2018, 15:57
C++
1
2
        m_vector = new int[m_size];
        memset(m_vector, 0, sizeof(m_vector));
Зануляются первые sizeof(m_vector) байт.
Наверное, имелось ввиду m_size * sizeof(*m_vector).
0
 Аватар для QuakerRUS
1469 / 1010 / 456
Регистрация: 30.10.2017
Сообщений: 2,799
09.08.2018, 15:59
Rastrizh, у меня без ошибок работает. Покажите весь код, который у вас сейчас получился.
0
0 / 0 / 0
Регистрация: 30.12.2015
Сообщений: 7
09.08.2018, 16:00  [ТС]
Вот так сейчас выглядит код:
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
#include <cstring>
 
class vec
{
public:
    vec()
    {
        m_size = offset;
        m_len = 0;
        m_vector = new int[m_size];
    }
    vec(size_t size)
    {
        m_size = size;
        m_len = 0;
        m_vector = new int[m_size];
    }
    vec(const vec& orig)
        :
        m_size(orig.m_size),
        m_len(orig.m_len),
        m_vector(nullptr)
    {
        if (m_vector != nullptr)
            delete[] m_vector;
 
        m_vector = new int[m_size];
        for (size_t i = 0; i < m_len; ++i)
        {
            m_vector[i] = orig.m_vector[i];
        }
    }
    ~vec()
    {
        if (m_vector != nullptr)
        {
            delete[] m_vector;
        }
    }
    size_t GetSize()
    {
        return m_size;
    }
    size_t GetLength()
    {
        return m_len;
    }
    int* GetValue()
    {
        return m_vector;
    }
    vec& operator= (const vec& rhs)
    {
        if (m_vector != nullptr)
            delete[] m_vector;
 
        m_len = rhs.m_len;
        m_vector = new int[m_size];
        for (size_t i = 0; i < m_len; ++i)
        {
            m_vector[i] = rhs.m_vector[i];
        }
        return *this;
    }
    int& operator[] (size_t index)
    {
        return m_vector[index];
    }
    bool operator== (const vec& rhs)
    {
        if (m_len != rhs.m_len)
            return false;
        for (unsigned int i = 0; i < m_len; ++i)
        {
            if (m_vector[i] != rhs.m_vector[i])
                return false;
        }
        return true;
    }
    bool operator!= (const vec& rhs)
    {
        if (!(this == &rhs))
            return true;
        return false;
    }
    void push_back(int value)
    {
        if (m_len == m_size)
        {
            m_size = m_size * (m_size / 2);
            int* temp_vector = m_vector;
            m_vector = new int[m_size];
            for (size_t i = 0; i < m_len; ++i)
            {
                m_vector[i] = temp_vector[i];
            }
            delete[] temp_vector;
        }
        m_vector[m_len] = value;
        m_len++;
    }
    void erase(unsigned int pos)
    {
        m_vector[pos] = m_vector[m_len - 1];
        --m_len;
    }
    void erase(unsigned int begin, unsigned int end)
    {
        for (unsigned int i = begin; i <= end; ++i)
        {
            m_vector[i] = m_vector[m_len - i - 1];
 
        }
        m_len -= end - begin;
    }
    void pop_back()
    {
        m_vector[m_len - 1] = 0;
        --m_len;
    }
private:
    static constexpr size_t offset = 8;
    size_t m_size;
    size_t m_len;
    int* m_vector;
};
И он по прежнему выдает ту же ошибку
0
 Аватар для QuakerRUS
1469 / 1010 / 456
Регистрация: 30.10.2017
Сообщений: 2,799
09.08.2018, 16:06
Rastrizh, вы неправильно вставили те фрагменты, которые я вам написал. Откуда, например, 22я строка?

Добавлено через 2 минуты
В operator= тоже строки не хватает из моего кода.
1
0 / 0 / 0
Регистрация: 30.12.2015
Сообщений: 7
09.08.2018, 16:07  [ТС]
В оператор присваивания не вставил строку:
C++
1
m_size = rhs.m_size;
Все работает, спасибо вам QuakerRUS большое
0
 Аватар для QuakerRUS
1469 / 1010 / 456
Регистрация: 30.10.2017
Сообщений: 2,799
09.08.2018, 16:09
Rastrizh, 22ю строку не забудьте удалить, иначе у вас утечка памяти будет.
0
 Аватар для Kuzia domovenok
4268 / 3327 / 926
Регистрация: 25.03.2012
Сообщений: 12,532
Записей в блоге: 1
09.08.2018, 16:35
Цитата Сообщение от QuakerRUS Посмотреть сообщение
Не забываем очищать массивы перед очисткой указателя.
имелось в виду очищать память m_vector в конструкторе? Ну зачееем? Конструктор он гарантированно создаёт новый объект, под поля которого память до этого никакая не выделялась!
1
 Аватар для QuakerRUS
1469 / 1010 / 456
Регистрация: 30.10.2017
Сообщений: 2,799
09.08.2018, 16:41
Kuzia domovenok, да, это я затупил что то, спасибо.

Добавлено через 3 минуты
Rastrizh, конструктор vec(const vec& orig) у вас изначально правильный был, проверка на непустоту m_vector там лишняя, извиняюсь за дезынформацию.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
09.08.2018, 16:41
Помогаю со студенческими работами здесь

Ошибка при вызове деструктора
Программа компилиться нормально,но после выполнения system(&quot;pause&quot;); выползает непонятное окно,и указывает на ошибку в деструкторе.В чем...

Ошибка при вызове деструктора
Не могу дописать лабу... Надо создать 4 класса, описать поля и методы. Выкладываю исходники: Самый главный класс - Order. Выбивает ошибку в...

Ошибка при вызове деструктора
Всем привет ! Есть класс class building { private: string *location_street; unsigned int *number_of_building; public...

Ошибка при вызове деструктора
Добрый вечер! Почему при вызове деструктора вылетает ошибка после компиляции кода? #include &lt;conio.h&gt; #include &lt;iostream&gt; ...

При вызове деструктора возникает ошибка Debug Assertion Failed!
вот код программы #include &lt;iostream&gt; #include &lt;conio.h&gt; using namespace std; class String { private:


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

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Обработчик клика мыши в браузере ПК и касания экрана в браузере на мобильном устройстве
8Observer8 02.02.2026
Содержание блога Для начала пошагово создадим рабочий пример для подготовки к экспериментам в браузере ПК и в браузере мобильного устройства. Потом напишем обработчик клика мыши и обработчик. . .
Философия технологии
iceja 01.02.2026
На мой взгляд у человека в технических проектах остается роль генерального директора. Все остальное нейронки делают уже лучше человека. Они не могут нести предпринимательские риски, не могут. . .
SDL3 для Web (WebAssembly): Вывод текста со шрифтом TTF с помощью SDL3_ttf
8Observer8 01.02.2026
Содержание блога В этой пошаговой инструкции создадим с нуля веб-приложение, которое выводит текст в окне браузера. Запустим на Android на локальном сервере. Загрузим Release на бесплатный. . .
SDL3 для Web (WebAssembly): Сборка C/C++ проекта из консоли
8Observer8 30.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
SDL3 для Web (WebAssembly): Установка Emscripten SDK (emsdk) и CMake для сборки C и C++ приложений в Wasm
8Observer8 30.01.2026
Содержание блога Для того чтобы скачать Emscripten SDK (emsdk) необходимо сначало скачать и уставить Git: Install for Windows. Следуйте стандартной процедуре установки Git через установщик. . . .
SDL3 для Android: Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 29.01.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами. Версия v3 была полностью переписана на Си, в. . .
Инструменты COM: Сохранение данный из VARIANT в файл и загрузка из файла в VARIANT
bedvit 28.01.2026
Сохранение базовых типов COM и массивов (одномерных или двухмерных) любой вложенности (деревья) в файл, с возможностью выбора алгоритмов сжатия и шифрования. Часть библиотеки BedvitCOM Использованы. . .
SDL3 для Android: Загрузка PNG с альфа-каналом с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 28.01.2026
Содержание блога SDL3 имеет собственные средства для загрузки и отображения PNG-файлов с альфа-каналом и базовой работы с ними. В этой инструкции используется функция SDL_LoadPNG(), которая. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru