Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Проблема с приложением :\

318
27 апреля 2007 года
nof
193 / / 03.04.2006
Народ, написал сетевое приложение под msvc 2005 с mfc.
Всё вроде бы нормально, но через некоторое время (оно варьируется), программа выводит сообщение Out of memory и перестаёт реагировать на нажатия.. Я всё проверил - везде где malloc, всегда юзаю free(), все создаваемые объекты в OnPaint удаляю через DeleteObject и DeleteDC.. Может есть какой нюанс, который я упустил? При каких абстоятельсвах эта ошибка чаще всего всплывает?

У меня есть подозрение. Юзаю структуру:

 
Код:
typedef struct {
    int ticker;
    short id;
    short global_id;
    byte group;
    float x;
    float y;
    float z;
} DROP;
DROP *drop;

Память под указатель выделяю так:
 
Код:
drop = (DROP *)malloc(sizeof(DROP) * (DROPMAX + 1));
memset(drop, '\x00', sizeof(DROP)*DROPMAX);

DROPMAX - количество экземпляров структуры.
Так можно с массивом структур работать?

Зарнее спасибо! Уже неделю парюсь с этим багом...
391
27 апреля 2007 года
Archie
562 / / 03.02.2005
А зачем ты выделяешь DROPMAX+1, если тебе нужно DROPMAX экземпляров? В любом случае, если освобождаешь все, что выделил, то проблем быть не должно. Юзай отладчик.
240
27 апреля 2007 года
aks
2.5K / / 14.07.2006
На самом деле утечка может быть где угодно, даже в самых неожиданных местах. =))
Кстати:
Цитата: nof
объекты в OnPaint удаляю через DeleteObject и DeleteDC..


зачем в обработчике сообщения отрисовки(!!!) что то создавать или удалять???

318
27 апреля 2007 года
nof
193 / / 03.04.2006
Цитата: aks
На самом деле утечка может быть где угодно, даже в самых неожиданных местах. =))
Кстати:

зачем в обработчике сообщения отрисовки(!!!) что то создавать или удалять???


Эм, а так разве нелья?

void CProjectDlg::OnPaint() {
CPaintDC dc(this); // device context for painting

if (IsIconic()) {
SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

// Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;

// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
} else {
CDC mapDc;

CBitmap m_bmp;

mapDc.CreateCompatibleDC(&dc);
m_bmp.CreateCompatibleBitmap(&dc, 100, 100);
mapDc.SelectObject(&m_bmp);

mapDc.SelectObject(brush); // brush инициализирую глобально
mapDc.PatBlt(0, 0, 100, 100, PATCOPY);
mapDc.Rectangle(0, 0, 100, 100);

mapDc.Ellipse(100 / 2 - 4, 100 / 2 - 4, 100 / 2 + 4, 100 / 2 + 4);

dc.BitBlt(0, 0, 100, 100, &mapDc, 0, 0, SRCCOPY);

dc.ReleaseOutputDC();
dc.DeleteDC();

mapDc.DeleteDC();
m_bmp.DeleteObject();

CDialog::OnPaint();
}
}


А затем когда надо обновляю окно:
InvalidateRect(0, true);
UpdateWindow();

15K
27 апреля 2007 года
ncode
9 / / 04.04.2006
Вот это:
 
Код:
dc.ReleaseOutputDC();
dc.DeleteDC();

mapDc.DeleteDC();
m_bmp.DeleteObject();

делать не обязательно, так как все это вызывается автоматически при выходе из OnPaint() для локальных объектов.
Утечки памяти для MFC проекта должны быть по умолчанию быть видны в окне дебагера после завершения программы. Если они не видны, то их либо нет либо они отключены.
Для WinAPI проекта отображение утечек памяти включается строчкой типа (не знаю работает ли это для MFC):
 
Код:
...
#include <crtdbg.h>
...
//entry point
int WINAPI _tWinMain(HINSTANCE instance, HINSTANCE /*prev_instance*/, LPTSTR /*cmd_line*/, int wnd_show)
{
    //DEBUG: show memory leaks at application exit
    _CrtSetDbgFlag(_CRTDBG_LEAK_CHECK_DF|_crtDbgFlag);
...
}
11K
27 апреля 2007 года
Ireul
90 / / 15.06.2006
Не трогай, ради бога CPaintDC! Его деструктор сам о нём позаботицца.
Вроде ликов нету. Значит ошибка в другом месте.

mapDc.DeleteDC();
m_bmp.DeleteObject();

Эти 2 строчки здесь действительно нужны. В каком порядке компилятору захочеться уничтожать эти объекты - определяется в левой ноге Б.Г.

А вот вызывать родительский OnPaint - это вы, сударь, зря делаете... Ибо он наверняк может ещё новый контекст попытаться создать, а то что вы сотворили со старым, аннигилировав его тотально, ему при этом явно не на пользу...
Если так подумать - OnPaint чей бы то ни было вообще вызывать нельзя...

И вообще, внеэкранные контексты и битмапы для них лучше делать через указатели и new/delete - тогда ты точно сам определяешь место и время их смерти ;)
318
27 апреля 2007 года
nof
193 / / 03.04.2006
Цитата: ncode
Вот это:
 
Код:
dc.ReleaseOutputDC();
dc.DeleteDC();

mapDc.DeleteDC();
m_bmp.DeleteObject();

делать не обязательно, так как все это вызывается автоматически при выходе из OnPaint() для локальных объектов.
Утечки памяти для MFC проекта должны быть по умолчанию быть видны в окне дебагера после завершения программы. Если они не видны, то их либо нет либо они отключены.


Обааа, огромное спасибо за наводку. Попробовал дебаг, программа тут же упала написав:

Цитата:

Cannot Release Output hDC on Attached CDC.
Detected memory leaks!
Dumping objects ->
d:\myprojects\hookdll\prj\prj\prjdlg.cpp(186) : {95} client block at 0x003594B8, subtype c0, 232 bytes long.
a CPage2 object at $003594B8, 232 bytes long
f:\rtm\vctools\vc7libs\ship\atlmfc\src\mfc\strcore.cpp(141) : {91} normal block at 0x00357E50, 29 bytes long.
Data: < >x > EC 97 3E 78 0C 00 00 00 0C 00 00 00 01 00 00 00
f:\rtm\vctools\vc7libs\ship\atlmfc\src\mfc\strcore.cpp(141) : {90} normal block at 0x00357DF8, 24 bytes long.
Data: < >x > EC 97 3E 78 07 00 00 00 07 00 00 00 01 00 00 00
f:\rtm\vctools\vc7libs\ship\atlmfc\src\mfc\strcore.cpp(141) : {89} normal block at 0x00357D50, 105 bytes long.
Data: < >xX X > EC 97 3E 78 58 00 00 00 58 00 00 00 01 00 00 00
d:\myprojects\hookdll\prj\prj\prjdlg.cpp(172) : {87} client block at 0x00357C90, subtype c0, 132 bytes long.
a CPage1 object at $00357C90, 132 bytes long
d:\myprojects\hookdll\prj\prj\prjdlg.cpp(161) : {86} normal block at 0x00357C40, 16 bytes long.
Data: <d h > 64 00 00 00 0D 00 00 00 68 01 00 00 11 01 00 00
f:\rtm\vctools\vc7libs\ship\atlmfc\src\mfc\strcore.cpp(141) : {72} normal block at 0x00357220, 49 bytes long.
Data: < >x > EC 97 3E 78 05 00 00 00 20 00 00 00 01 00 00 00
Object dump complete.
The program '[1148] prj.exe: Native' has exited with code 3 (0x3).



Убрал:
dc.ReleaseOutputDC();
dc.DeleteDC();
Запустил снова дебаг. Программа запустилась, но при нажатии не первую же кнопку снова упала... Ошибка такая же как выше, но предложения "Cannot Release Output hDC on Attached CDC." не было...
Возможно ли как-то по этому дампу отследить где memory leak?

2Ireul а как тогда экран перерисовывать?

11K
27 апреля 2007 года
Ireul
90 / / 15.06.2006
Убери CDialog::OnPaint();

Вызов OnPaint() происходит по сообщению, ручные вызовы имелись в виду, когда я говорил что вызывать OnPaint нельзя.
240
30 апреля 2007 года
aks
2.5K / / 14.07.2006
Цитата: nof
Эм, а так разве нелья?


Зачем каждый раз в обработчике перерисовки создавать битмапы, чтото на них рисовать удалять? Он же должен только перерисовывать изменившеюся облать и все.
Ну рисуй там де действительно что то меняется. Рисуй на виртуальном контектсе и битмапе например, в в товем OnPain делай BitBlt оттуда.

Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог