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

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

10.02.2018, 23:55. Показов 3643. Ответов 5
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Всем привет.
Пытаюсь написать что-то типа динамического массива строк, и все шло довольно хорошо пока не начал писать деструктор.
Проблема в том, что деструктор отрабатыват нормально(в отладчике видно, что динамически выделенная память осободилась)
Но при выходе из мэйна выдает:

Debug Assertion Failed
Expression: __CrtisValidHeapPointer(block)

Предположение:Подозреваю, что удаляю в деструкторе что-то лишнее, в итоге программа при выходе пытается повторно очистить память, только в таком случае не понимаю что.

В общем прошу помочь кто-чем может.

Спасибо.

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
template<class Type> class DStringList 
{
private:
    int element_count = 0;
    struct DString
    {
        Type* string = NULL;
        DString* next_DString = NULL;
    };
 
    DString* FirstDString = NULL;
    DString* LastDString = NULL;
    
public:
    DStringList();
    ~DStringList();
 
    void add_string(Type* string);
    int get_elements_count(void) { return element_count; }
 
 
    Type *operator[](int index)
    {
        int i = 0;
        DString* start = NULL;
        for (start = FirstDString; start != NULL; start = start->next_DString)
        {
            if (i == index) break;
            i++;
        }
 
        return start->string;
    }
    
};
 
template<class Type> DStringList<Type>::DStringList()
{
}
 
template<class Type> DStringList<Type>::~DStringList() 
{
    DString* destructor_ptr;
 
    for (destructor_ptr = FirstDString; destructor_ptr != NULL; destructor_ptr = destructor_ptr->next_DString)
        delete[] destructor_ptr->string;
 
    for (destructor_ptr = FirstDString->next_DString; destructor_ptr != NULL; destructor_ptr = destructor_ptr->next_DString)
    {
        delete FirstDString;
        FirstDString = destructor_ptr;
    }
}
 
template<class Type> void DStringList<Type>::add_string(Type * string)
{
    int string_len = 0;
    for (string_len = 0; string[string_len] != '\0'; string_len++);
 
 
    DString* new_DString = new DString;
    if (FirstDString == NULL) FirstDString = new_DString;
 
    new_DString->string = new Type[string_len + 1];
 
    for (int i = 0; i < string_len; i++)
        new_DString->string[i] = string[i];
    new_DString->string[string_len] = '\0';
 
    if (LastDString != NULL)
        LastDString->next_DString = new_DString;
        
    LastDString = new_DString;
 
    element_count++;
}
 
 
 
 
 
int main(int argc, char** argv) {
    
    DStringList<WCHAR> list;
 
    list.add_string(L"Hello World");
    list.add_string(L"World Hello");
 
    wprintf(L"%d\n", list.get_elements_count());
    wprintf(L"%s\n", list[0]);
    wprintf(L"%s\n", list[1]);
    
    list.~DStringList();
    
 
    getchar();
}
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
10.02.2018, 23:55
Ответы с готовыми решениями:

Ошибка в деструкторе
есть базовый абстрактный класс и есть производный от него: #ifndef EMPLOY_H #define EMPLOY_H class Employee { public: ...

Ошибка в деструкторе
Программа работает без ошибок и полный её код не выкладываю. Но при выходе из программы получаю вот такую ошибку: В программе я...

Ошибка в деструкторе
Когда удаляю объект класса hotel, в деструкторе вызывается delete для поля этого объекта - динамически созданного связного списка. И...

5
710 / 356 / 104
Регистрация: 09.02.2018
Сообщений: 805
11.02.2018, 10:48
epitxx, с конца удаляй:
C++
1
2
3
4
5
6
7
8
9
10
11
12
template<class Type> DStringList<Type>::~DStringList() 
{
    DString* destructor_ptr;
    if(FirstDString!=NULL){
        while (FirstDString!=LastDString){
            for (destructor_ptr=FirstDString; destructor_ptr->next_DString!=LastDString; destructor_ptr=destructor_ptr->next_DString);
            delete LastDString;
            LastDString=destructor_ptr;
        }
        delete LastDString;
    }
}
0
nd2
3438 / 2817 / 1249
Регистрация: 29.01.2016
Сообщений: 9,427
11.02.2018, 13:28
Цитата Сообщение от epitxx Посмотреть сообщение
C++
1
list.~DStringList();
Не нужно этого делать. Деструктор автоматически вызывается при выходе из области, где был создан list (main()).
0
0 / 0 / 0
Регистрация: 18.01.2018
Сообщений: 10
11.02.2018, 16:05  [ТС]
По поводу автоматического вызова деструктора верно, но возникает еще одна проблема.

Вот такой код:
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
WCHAR* l;
 
void Test()
{
    DStringList<WCHAR> list;
 
    list.add_string(L"Hello World");
    list.add_string(L"World Hello");
 
    wprintf(L"%d\n", list.get_elements_count());
    wprintf(L"%s\n", list[0]);
    wprintf(L"%s\n", list[1]);
 
    l = list[0];
    
    wprintf(L"Test l:%s\n", l);
    //list.~DStringList();
    wprintf(L"Test2 l:%s\n", l);
}
 
 
 
int main(int argc, char** argv) {
    
    Test();
 
    wprintf(L"Main l:%s\n", l);
 
    l[0] = 'A';
    l[1] = '\0';
 
    wprintf(L"Main l:%s\n", l);
 
    getchar();
}
При выходе из Test() деструктор действительно срабатывает, но я все еще могу обратиться к строке в структуре DString.

Вот результат работы:
2
Hello World
World Hello
Test l:Hello World
Test2 l:Hello World
Main l:??????????????
Main l:A
0
nd2
3438 / 2817 / 1249
Регистрация: 29.01.2016
Сообщений: 9,427
11.02.2018, 16:41
Цитата Сообщение от epitxx Посмотреть сообщение
При выходе из Test() деструктор действительно срабатывает, но я все еще могу обратиться к строке в структуре DString.
И что? delete, как известно, не удаляет, а ОСВОБОЖДАЕТ память: память помечается как свободная. Что там находится после этого - зависит от разного, и к самому освобождению памяти отношения не имеет.
1
0 / 0 / 0
Регистрация: 18.01.2018
Сообщений: 10
11.02.2018, 17:38  [ТС]
Тогда все прекрасно, большое спасибо за ответ
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
11.02.2018, 17:38
Помогаю со студенческими работами здесь

Классы - ошибка в деструкторе
У меня сейчас такое &quot;задание&quot;: опередить класс длинного целого числа (длинная арифметика), для сохранения которого необходимо использовать...

Ошибка при работе delete в деструкторе
enum place { first = 1, second }; class Passanger { public: Passanger(); void Call(); void PushButton(); int...

Ошибка в деструкторе или перегрузке оператора C++ ООП
#include &lt;iostream&gt; #include &lt;iomanip&gt; #include &lt;conio.h&gt; #include &lt;math.h&gt; #include &lt;windows.h&gt; using namespace std; ...

Возникает ошибка при удалении динамического массива символов в деструкторе класса
Всем привет. Есть приватная переменная, указатель на строку wchar_t *pUAgent; В конструкторе я ее инициализирую: pUAgent =...

При работе с free в деструкторе ошибка "Invalid address specified to RtlValidateHeap"
Доброго времени суток, господа эксперты и дамы эксперты. Объясните пожалуйста почему программа вылетает с ошибкой &quot;program.exe...


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

Или воспользуйтесь поиском по форуму:
6
Ответ Создать тему
Новые блоги и статьи
Перемещение выделенных строк ТЧ из одного документа в другой
Maks 30.03.2026
Реализация из решения ниже выполнена на примере нетипового документа "ВыдачаОборудованияНаСпецтехнику" с единственной табличной частью "ОборудованиеИКомплектующие" разработанного в конфигурации КА2. . . .
Functional First Web Framework Suave
DevAlt 30.03.2026
Sauve. IO Апнулись до NET10. Из зависимостей один пакет, работает одинаково хорошо как в режиме проекта так и в интерактивном режиме. из сложностей - чисто функциональный подход. Решил. . .
Автоматическое создание документа при проведении другого документа
Maks 29.03.2026
Реализация из решения ниже выполнена на нетиповых документах, разработанных в конфигурации КА2. Есть нетиповой документ "ЗаявкаНаРемонтСпецтехники" и нетиповой документ "ПланированиеСпецтехники". В. . .
Настройка движения справочника по регистру сведений
Maks 29.03.2026
Решение ниже реализовано на примере нетипового справочника "ТарифыМобильнойСвязи" разработанного в конфигурации КА2, с целью учета корпоративной мобильной связи в коммерческом предприятии. . . .
Автозаполнение реквизита при выборе элемента справочника
Maks 27.03.2026
Программный код из решения ниже на примере нетипового документа "ЗаявкаНаРемонтСпецтехники" разработанного в конфигурации КА2. При выборе "Спецтехники" (Тип Справочник. Спецтехника), заполняется. . .
Сумматор с применением элементов трёх состояний.
Hrethgir 26.03.2026
Тут. https:/ / fips. ru/ EGD/ ab3c85c8-836d-4866-871b-c2f0c5d77fbc Первый документ красиво выглядит, но без схемы. Это конечно не даёт никаких плюсов автору, но тем не менее. . . всё может быть. . .
Автозаполнение реквизитов при создании документа
Maks 26.03.2026
Программный код из решения ниже размещается в модуле объекта документа, в процедуре "ПриСозданииНаСервере". Алгоритм проверки заполнения реализован для исключения перезаписи значения реквизита,. . .
Команды формы и диалоговое окно
Maks 26.03.2026
1. Команда формы "ЗаполнитьЗапчасти". Программный код из решения ниже на примере нетипового документа "ЗаявкаНаРемонтСпецтехники" разработанного в конфигурации КА2. В качестве источника данных. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru