Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
dleen
65 / 3 / 2
Регистрация: 01.07.2014
Сообщений: 38
#1

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

11.09.2014, 17:57. Просмотров 1004. Ответов 9
Метки нет (Все метки)

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

---------------------------
Microsoft Visual C++ Debug Library
---------------------------
Debug Assertion Failed!

Program: ...n\Documents\Visual Studio 2010\Projects\laba3\Debug\laba3.exe
File: f:\dd\vctools\crt_bld\self_x86\crt\src\dbgdel.cpp
Line: 52

Expression: _BLOCK_TYPE_IS_VALID(pHead->nBlockUse)

For information on how your program can cause an assertion
failure, see the Visual C++ documentation on asserts.

(Press Retry to debug the application)
---------------------------
Прервать Повтор Пропустить
---------------------------
В программе я создаю массив объектов используя вот такой конструктор:
код1
C++
1
2
3
4
5
6
7
8
9
10
11
12
Bus::Bus(char *pn, char ta, int nr, int kb, int zb, float vo, float vp) //конструктор с параметрами
{
    punktNaznachenija = new char[32];
 
    punktNaznachenija=pn;
    tipAvtobusa=ta;
    nomerReisa=nr;
    kolBiletov=kb;
    zenaBileta=zb;
    vremiaOtpravlenija=vo;
    vremiaPribitija=vp;
}
И вот такой деструктор:

код2
C++
1
2
3
4
Bus::~Bus() //деструктор
{ 
   delete [] punktNaznachenija; 
}

Обнаружил, что если закомментировать осовобождение выделенной под строку punktNaznachenija в деструкторе памяти, то ошибка винды при выходе из проги исчезает. Т.е. вот так работает без ошибок:
код3
C++
1
2
3
4
Bus::~Bus() //деструктор
{ 
   //delete [] punktNaznachenija; 
}
Вопрос: Почему возникает ошибка при выходе из программы и есть ли другие, отличные от код3, способы её устранения?

p.s. Если данных не достаточно могу выложить весь код программы. Он хоть и длинноват, около 300 строк... Но зато разбит на хэдер с описанием класса и две сpp-шки с описаниями методов и main-функции.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
11.09.2014, 17:57
Я подобрал для вас темы с готовыми решениями и ответами на вопрос Ошибка в деструкторе (C++):

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

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

Классы - ошибка в деструкторе
У меня сейчас такое "задание": опередить класс длинного целого числа (длинная...

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

Ошибка в деструкторе или перегрузке оператора C++ ООП
#include <iostream> #include <iomanip> #include <conio.h> #include <math.h>...

Возникает ошибка при удалении динамического массива символов в деструкторе класса
Всем привет. Есть приватная переменная, указатель на строку wchar_t...

9
alsav22
5438 / 4833 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
11.09.2014, 18:00 #2
Цитата Сообщение от dleen Посмотреть сообщение
Почему возникает ошибка при выходе из программы
Гед-то память портится.

Добавлено через 1 минуту
Вот это что? Выделили память и тут же её потеряли?
Цитата Сообщение от dleen Посмотреть сообщение
C++
1
2
punktNaznachenija = new char[32];
punktNaznachenija=pn;
0
dleen
65 / 3 / 2
Регистрация: 01.07.2014
Сообщений: 38
11.09.2014, 18:05  [ТС] #3
Почему потерял? Выделил память и положил в неё значение pn. Ну по крайней мерее мне сейчас кажется что именно так и должно происходить. не?
1
alsav22
5438 / 4833 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
11.09.2014, 18:09 #4
Цитата Сообщение от dleen Посмотреть сообщение
не?
Не. Выделили память под указатель (в указателе адрес начала памяти) и присвоили указателю другой адрес.

Добавлено через 2 минуты
Цитата Сообщение от dleen Посмотреть сообщение
Выделил память и положил в неё значение pn.
Если хотите строку в массив поместить, то нужно через strcpy().
0
dleen
65 / 3 / 2
Регистрация: 01.07.2014
Сообщений: 38
11.09.2014, 18:19  [ТС] #5
В конструкторе сделал вот так:
C++
1
2
3
4
5
6
7
8
9
10
11
12
Bus::Bus(char *pn, char ta, int nr, int kb, int zb, float vo, float vp) //конструктор с параметрами
{
    pn = new char[32];
    punktNaznachenija=pn;
    tipAvtobusa=ta;
    nomerReisa=nr;
    kolBiletov=kb;
    count+=kolBiletov; //статическая переменная
    zenaBileta=zb;
    vremiaOtpravlenija=vo;
    vremiaPribitija=vp;
}
В деструкторе оставил вот так:
C++
1
2
3
4
Bus::~Bus() //деструктор
{ 
     delete [] punktNaznachenija; 
}
Ошибки при выходе из программы нет. Но чувствую что все равно где то накосячил

Добавлено через 6 минут
Цитата Сообщение от alsav22 Посмотреть сообщение
Если хотите строку в массив поместить, то нужно через strcpy().
Не, в массив не хочу. В переменную объекта я её помещаю. А уже потом из объектов массив собираю. Вот так вобщем в main всё выглядит:

C++
1
Bus b20[3]={ Bus("Berlin", 'A', 1, 50, 200, 11.11, 19.45), Bus("Moscow", 'A', 2, 50, 200, 19.46, 18.11), Bus("Moscow", 'C', 3, 50, 124, 11.11, 22.00) }; //создается массив объектов конструктором с параметрами
0
DrOffset
7518 / 4514 / 1097
Регистрация: 30.01.2014
Сообщений: 7,362
11.09.2014, 18:31 #6
Цитата Сообщение от dleen Посмотреть сообщение
Но чувствую что все равно где то накосячил
Ага.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
Bus::Bus(char const * pn, char ta, int nr, int kb, int zb, float vo, float vp) //конструктор с параметрами
{
    punktNaznachenija = new char[strlen(pn) + 1];
    strcpy(punktNaznachenija, pn);
 
    tipAvtobusa=ta;
    nomerReisa=nr;
    kolBiletov=kb;
    count+=kolBiletov; //статическая переменная
    zenaBileta=zb;
    vremiaOtpravlenija=vo;
    vremiaPribitija=vp;
}
Добавлено через 1 минуту
Цитата Сообщение от dleen Посмотреть сообщение
Не, в массив не хочу.
C-строка - это и есть массив.
Вообще, использование здесь std::string более уместно. Если предполагается работать со строкой как с объектом, а не как с массивом.
1
Справлюсь
23 / 23 / 14
Регистрация: 24.07.2014
Сообщений: 209
11.09.2014, 18:34 #7
вместо punktNaznachenija=pn; нужно strcpy(punktNaznachenija,pn);
0
alsav22
5438 / 4833 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
11.09.2014, 18:35 #8
Цитата Сообщение от dleen Посмотреть сообщение
В переменную объекта я её помещаю.
Что помещаете? В параметрах указатель на строковый литерал, под этот указатель выделяете память (адрес строкового литерал при этом теряется), адрес пустой памяти заносите в punktNaznachenija.
Цитата Сообщение от alsav22 Посмотреть сообщение
Если хотите строку в массив поместить, то нужно через strcpy().
1
dleen
65 / 3 / 2
Регистрация: 01.07.2014
Сообщений: 38
11.09.2014, 19:11  [ТС] #9
DrOffset, да, так на много круче. Спасибо!

Аналогичный косяк я допустил и в конструкторе копий. Исправил. Работает. Но остался вопрос (см. строку 4. кода):

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Bus::Bus (const Bus &object) //конструктор копии
{
//  punktNaznachenija = new char [32];                                   //было
    punktNaznachenija = new char [strlen(object.punktNaznachenija) +1];  //стало. но не уверен что правильно понимаю зачем тут +1. В object.punktNaznachenija у нас же уже есть нуль символ. Или он в strlen не считается ?
 
 
//  punktNaznachenija=object.punktNaznachenija;             //было
    strcpy (punktNaznachenija, object.punktNaznachenija);   //стало
    tipAvtobusa=object.tipAvtobusa;
    nomerReisa=object.nomerReisa;
    kolBiletov=object.kolBiletov;
    zenaBileta=object.zenaBileta;
    vremiaOtpravlenija=object.vremiaOtpravlenija;
    vremiaPribitija=object.vremiaPribitija;
}
Добавлено через 12 минут
Цитата Сообщение от alsav22 Посмотреть сообщение
Что помещаете? В параметрах указатель на строковый литерал, под этот указатель выделяете память (адрес строкового литерал при этом теряется), адрес пустой памяти заносите в punktNaznachenija.
Спасибо. Перечитаю сегодня раз 10 ваши слова, чтобы окончательно въехать. Но уже пора убегать. А то опоздаю туда куда спешу
0
DrOffset
7518 / 4514 / 1097
Регистрация: 30.01.2014
Сообщений: 7,362
11.09.2014, 19:16 #10
Цитата Сообщение от dleen Посмотреть сообщение
Или он в strlen не считается ?
Да. Возвращает "чистую" длину строки, без учета нуль-символа.
0
11.09.2014, 19:16
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
11.09.2014, 19:16
Привет! Вот еще темы с решениями:

При работе с free в деструкторе ошибка "Invalid address specified to RtlValidateHeap"
Доброго времени суток, господа эксперты и дамы эксперты. Объясните...

Зависание на деструкторе.
Всем доброго времени суток! Проблема такая: есть класс cData в нём...

Повисание в деструкторе
Есть такой код: //staff.h class staff abstract { protected: int...

Освобождение памяти в деструкторе
Объясните, пожалуйста, что я делаю не правильно. Есть класс: class a{...


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

Или воспользуйтесь поиском по форуму:
10
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru