Я в этом не шарю
4 / 4 / 3
Регистрация: 03.09.2014
Сообщений: 191
1

При попытке очистки классов, деструктор падает

19.09.2014, 11:45. Показов 597. Ответов 6
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
вообщем при создании окна (WM_CREATE). я создаю класс и присваиваю его поинтер в USERDATA.
внутри класса я объявляю массив окон со своими классами в USERDATA.
этот самый массив пытаюсь удалить при WM_CLOSE и WM_DESTROY, но удаление(delete), когда хочет, тогда и срабатывает.
а если не сработает, то деструктор просто перестаёт обработку оставшегося кода и всё.
вот класс:
C++
1
2
3
4
5
6
7
class ExListview
{
public:
    ExListview(HWND _hwnd);
    ~ExListview();
    HWND        item[itemssmax];
}
вот WM_CREATE:
C++
1
2
3
4
5
6
if (message==WM_CREATE)
    {
        ExListview*b = new ExListview(hwnd);
        SetWindowLongPtr(hwnd, GWLP_USERDATA, (ULONG)b);
        return 0;
    }
вот деструктор:
C++
1
2
3
4
5
6
7
8
ExListview::~ExListview()
{
    for(int i=0;i<itemssmax;i++)
    {
        ExList*a = GetExListviewItem(hwnd,i);
        if ((int)a)delete a;
    }
}
функция GetExListviewItem возвращает класс (ExList) присвоенный каждому окну item из класса ExListview.
деструктора у ExList нет.

так вот я пробовал проверять чему равно ExList*a.
пробовал создавать деструктор ExList с выводом текста.
пробовал ставить сообщения перед delete и после delete.
вышло что-то вроде
C++
1
2
3
4
5
6
7
8
9
10
11
    MessageBox(0,"start deleting","~ExListview",MB_ICONINFORMATION);
    for(int i=0;i<itemssmax;i++)
    {
        //MessageBox(0,"start item","~ExListview",MB_ICONINFORMATION);
        ExList*a = GetExListviewItem(hwnd,i);
        ShowInt((int)a,"before delete item");
        if ((int)a)delete a;
        ShowInt((int)a,"after delete item");
        //MessageBox(0,"finished item","~ExListview",MB_ICONINFORMATION);
    }
    MessageBox(0,"delete items","~ExListview",MB_ICONINFORMATION);
C++
1
2
3
4
ExList::~ExList()
{
    MessageBox(0,"delete exlist","~ExList",MB_ICONINFORMATION);
}
так вот, когда всё падает показывается только сообщение перед delete ("before delete item").
т.е. сообщения в ExList деструкторе нет и сообщения после delete тоже нет.
в чем я не прав?
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
19.09.2014, 11:45
Ответы с готовыми решениями:

Вылет при попытке очистки консоли
В программе много раз вызывается функция, которая очищает окно консоли с помощью команды ...

Непонятное сообщение при попытке очистки консоли
Доброго времени суток. OS - Mac OS, среда разработки - XCode. Хочу очистить консоль, пишу в...

Срабатывание точки останова при попытке очистки памяти
Здравствуйте! Суть задания - есть массив, заполненный случайными числами. Потом это массив нужно...

MySQL Падает при попытке изменения конфига
Доброй, чего-то я в корне недопонимаю. Есть VPS, на нём: # uname -a Linux...

6
Ушел с форума
Эксперт С++
16473 / 7436 / 1187
Регистрация: 02.05.2013
Сообщений: 11,617
Записей в блоге: 1
19.09.2014, 22:23 2
Цитата Сообщение от Segaman Посмотреть сообщение
этот самый массив пытаюсь удалить при WM_CLOSE и WM_DESTROY
Выберите что-то одно, иначе получится двойное удаление.

Цитата Сообщение от Segaman Посмотреть сообщение
SetWindowLongPtr(hwnd, GWLP_USERDATA, (ULONG)b);
Опасно !
Размер ULONG - 4 байта, размер указателя может быть 8 байт (на x64).

Цитата Сообщение от Segaman Посмотреть сообщение
if ((int)a)delete a;
Незачем проверять на NULL.
По стандарту, delete на нулевом указателе - разрешенная операция.
Про усечение ptr в int уже написал выше.

Цитата Сообщение от Segaman Посмотреть сообщение
ShowInt((int)a,"before delete item");
Снова усечение. Лучше какой-нибудь printf со спецификатором %p.

Цитата Сообщение от Segaman Посмотреть сообщение
в чем я не прав?
Хотелось бы видеть деструктор ExListview и функцию GetExListviewItem,
может ошибка там.
0
Я в этом не шарю
4 / 4 / 3
Регистрация: 03.09.2014
Сообщений: 191
22.09.2014, 15:48  [ТС] 3
Убежденный,
C++
1
2
3
4
5
6
7
8
/*=====================================================================================================*/
//получить класс элемента списка
ExList*GetExListviewItem(HWND hwnd, int slot)
{
    ExListview*a = (ExListview*)GetWindowLongPtr(hwnd, GWLP_USERDATA);
    return GetExList(a->item[slot]);
}
/*=====================================================================================================*/
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
ExListview::~ExListview()
{
    //MessageBox(0,"start deleting","~ExListview",MB_ICONINFORMATION);
    for(int i=0;i<itemssmax;i++)
    {
        //MessageBox(0,"start item","~ExListview",MB_ICONINFORMATION);
        ExList*a = GetExListviewItem(hwnd,i);
        //ShowInt((int)a,"before delete item");
        if ((int)a)delete a;
        //ShowInt((int)a,"after delete item");
        //MessageBox(0,"finished item","~ExListview",MB_ICONINFORMATION);
    }
}
компилирую я только 32битную версию. в 64 надобности нет.

Добавлено через 16 секунд
Убежденный,
C++
1
2
3
4
5
6
7
8
/*=====================================================================================================*/
//получить класс элемента списка
ExList*GetExListviewItem(HWND hwnd, int slot)
{
    ExListview*a = (ExListview*)GetWindowLongPtr(hwnd, GWLP_USERDATA);
    return GetExList(a->item[slot]);
}
/*=====================================================================================================*/
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
ExListview::~ExListview()
{
    //MessageBox(0,"start deleting","~ExListview",MB_ICONINFORMATION);
    for(int i=0;i<itemssmax;i++)
    {
        //MessageBox(0,"start item","~ExListview",MB_ICONINFORMATION);
        ExList*a = GetExListviewItem(hwnd,i);
        //ShowInt((int)a,"before delete item");
        if ((int)a)delete a;
        //ShowInt((int)a,"after delete item");
        //MessageBox(0,"finished item","~ExListview",MB_ICONINFORMATION);
    }
}
компилирую я только 32битную версию. в 64 надобности нет.
0
Я в этом не шарю
4 / 4 / 3
Регистрация: 03.09.2014
Сообщений: 191
26.09.2014, 16:29  [ТС] 4
Цитата Сообщение от Убежденный Посмотреть сообщение
Опасно !
Размер ULONG - 4 байта, размер указателя может быть 8 байт (на x64).
так и есть. на Windows 8 программа падает. Куда тогда можно писать указатель?
сосдавать массив ссылок с последующей идентификацией как-то не хочется.
0
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
32830 / 21168 / 8147
Регистрация: 22.10.2011
Сообщений: 36,428
Записей в блоге: 8
26.09.2014, 17:30 5
Цитата Сообщение от Segaman Посмотреть сообщение
Куда тогда можно писать указатель?
Туда же, но не надо приводить его к ULONG, приводи к LONG_PTR
0
Я в этом не шарю
4 / 4 / 3
Регистрация: 03.09.2014
Сообщений: 191
26.09.2014, 17:54  [ТС] 6
заменил ULONG на LONG_PTR, но на Windows 8 все равно падение при попытке записи в USERDATA.
даже если компилить в 64 бита
0
31 / 31 / 5
Регистрация: 24.09.2014
Сообщений: 243
30.09.2014, 20:19 7
Сделай проверку существования окна (IsWindow) в каждой функции, где оно используется.
"Отбрейк-пойнти" каждую функцию, нет ли где "нулевых" классов / переменных, к которым потом идёт обращение.
0
30.09.2014, 20:19
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
30.09.2014, 20:19
Помогаю со студенческими работами здесь

Программа падает при попытке вывести диалог
Ест проект QT (простите за грязный код, если кто ни-будь чего-нибудь посоветует, буду очень...

Программа падает при попытке записи элементов структуры
Есть такая структура struct Follower { //структура char Words; float Count; char kod; }; Она...

Приложение падает при попытке соединения через сокет
IPEndPoint ipEndPoint = new IPEndPoint(ip, port); Socket sListener = new...

При попытке обновить поле падает mysql на денвере
Запрос на грани фантастики: MySQL_Query(&quot;UPDATE `pages` SET `rus_name`='$name', `content`='$text',...


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

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

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru