Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > ESP was not properly saved across a function call


Автор: mrgloom 5.4.2012, 15:29
Run-Time Check Failure #0 - The value of ESP was not properly saved across a function call.  This is usually a result of calling a function declared with one calling convention with a function pointer declared with a different calling convention.

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

погуглил пишут, один из вариантов, что бьётся стэк.
как можно выловить ошибку? при каких действиях он вообще бьётся?

Автор: mrgloom 5.4.2012, 15:48
сделал clean+rebuild all
теперь пишет
Detected memory leaks! Dumping objects -> 


как можно отловить?

Автор: Earnest 5.4.2012, 16:52
Дамп этих самых ликов тебе в помощь.
Среда, как я понимаю MSVC? Тогда в начале каждого cpp-файла нужно вставить код:
Код

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

Это поможет сделать дамп ликов более вразумительным: тебя должен интересовать только самый верхний, остальные, как правило, следствие.
В дампе указано место создание и тип объекта.
Но может, ты и сам вспомнишь, где накосячил с памятью. Наиболее вероятные ошибки:
1) циклическая ссылка с умным указателем (т.е. А держит B, B держит A; возможны более длинные рекурсивнче цепочки)
2) невиртуальный деструктор в полиморфном объекте
3) тупое отсутствие delete, если вдруг ты используешь обычные указатели
4) неправильный delete для массива
...

Автор: mrgloom 6.4.2012, 09:09
обычно эти мемори лики возникают когда я завершаю программу на крестик или останавливаю дебаг в студии нажимая на стоп.
причем не все время, возможно при каких то моих действиях внутри.


такие дефайны я нашел у себя в проекте в некоторых местах, понять бы что это значит еще и что даёт.
Код

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif


причем попробовал включить в интеерсующий меня .cpp файл и теперь ругается на 
Код

new(std::nothrow)


прочитал тут еще 
http://msdn.microsoft.com/en-us/library/e5ewb1h3(v=vs.80).aspx

добавил сей код в stdafx.h
Код

#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>


но непонятно на каком месте надо вызывать _CrtDumpMemoryLeaks();


что мне даст анализ дампа памяти? 

Код

Detected memory leaks!
Dumping objects ->
C:\PROGRAM FILES\VISUAL STUDIO\MyProjects\leaktest\leaktest.cpp(20) : {18} 
normal block at 0x00780E80, 64 bytes long.
 Data: <                > CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD
Object dump complete.


например тут из полезной информации только строчка на которой это происходит (на 20 строчке как я понимаю leaktest.cpp(20) )
означает ли это, что реально на 20 строке происходит утечка или эта строчка обозначает что то другое?

Автор: mrgloom 6.4.2012, 09:29
да кстати написал #define _CRTDBG_MAP_ALLOC в stdafx.h  и все равно файл и строчку в которой произошли мемори лики не выводит

Автор: Earnest 6.4.2012, 11:03
Цитата(mrgloom @  6.4.2012,  10:09 Найти цитируемый пост)
такие дефайны я нашел у себя в проекте в некоторых местах, понять бы что это значит еще и что даёт.

Это подмена "обычного" new на специальный, который запоминает что, где, когда
Цитата(mrgloom @  6.4.2012,  10:09 Найти цитируемый пост)
причем попробовал включить в интересующий меня .cpp файл и теперь ругается на 

Да, такая засада есть: этот "специальный" new конфликтует с другими new с аргументами. Сталкивалась с этим, но не помню, как выкрутилась. 
Цитата(mrgloom @  6.4.2012,  10:09 Найти цитируемый пост)
означает ли это, что реально на 20 строке происходит утечка или эта строчка обозначает что то другое? 

Это строчка, в которой создан объект, оставшийся висеть. Если там ничего нет, то можно попробовать по содержимому и размеру понять, кто это. 
Цитата(mrgloom @  6.4.2012,  10:09 Найти цитируемый пост)
обычно эти мемори лики возникают когда я завершаю программу на крестик или останавливаю дебаг в студии нажимая на стоп.

Лики при остановке отладки в студии - это нормально: там скорее всего terminate работает, который за собой не чистит. А вот завершение по крестику должно быть нормальным. Лики всегда возникают только при завершении, ибо предполагается, что процесс должен освободить все, что занял. В процессе выполнения никто не знает, где утечка, а где нужный в настоящий момент объект.

Добавлено через 7 минут и 17 секунд
С ликами бесполезно бороться механически (т.е. ждать, что кто-то тебе укажет, где ты накосячил). Нужно включать голову по любому и анализировать свой код. Еще можно попробовать расхваливаемый автором анализатор кода ... какое-то Studio (не помню точно название, недавно тема опять была)

Автор: borisbn 6.4.2012, 11:32
Цитата(Earnest @  6.4.2012,  11:03 Найти цитируемый пост)
Нужно включать голову по любому и анализировать свой код

ну... и total debugging никто не отменял... логирование, заремливание кусков кода... return true в начале "подозрительных" функций...

Цитата(Earnest @  6.4.2012,  11:03 Найти цитируемый пост)
 какое-то Studio (не помню точно название, недавно тема опять была) 

http://www.viva64.com/ru/pvs-studio/

Добавлено через 3 минуты
гыыыы. пока искал ссылку
user posted image
это на заметку Thunderbolt

Автор: Earnest 6.4.2012, 11:42
Да, точно, оно.
Цитата(borisbn @  6.4.2012,  12:32 Найти цитируемый пост)
гыыыы. пока искал ссылку

Ну, строго говоря, то, что Гугель помнит запрос, вовсе не означает, что есть нужный ответ (т.е. этот самый крак).

Автор: mrgloom 16.4.2012, 09:50
мемори лик нашёл путем долгого ручного труда, как работает 
Цитата

Detected memory leaks!
Dumping objects ->

так и не понял, ибо не получилось выводить строчку кода на которой утечка.

и я так и не понял, не существует никаких дополнительных  средств\ методик?
может что порекомендуете почитать?


п.с. pvs studio платный, да и еще я так понимаю выдаёт кучу ненужных\подозрительных предупреждений.

Автор: Earnest 17.4.2012, 06:25
Цитата(mrgloom @  16.4.2012,  10:50 Найти цитируемый пост)
ибо не получилось выводить строчку кода на которой утечка.

Это бывает, если  в файле, где создается объект, нет нужной вставки (подмены new) - либо забыл, либо не твой код, либо ...

Ошибки с памятью проще не совершать, чем искать. Всегда, когда создаешь объект, думай, сколько он будет жить и где разрушаться. Лучше, чтобы создание и разрушение образовывали "скобки" (как бы замыкали код). Везде где можно, используй умные указатели, но помни о циклических ссылках.
Со временем привыкаешь, и такого рода ошибки становятся очень редкими.

Добавлено через 31 секунду
Цитата(mrgloom @  16.4.2012,  10:50 Найти цитируемый пост)
ибо не получилось выводить строчку кода на которой утечка.

Это бывает, если  в файле, где создается объект, нет нужной вставки (подмены new) - либо забыл, либо не твой код, либо ...

Ошибки с памятью проще не совершать, чем искать. Всегда, когда создаешь объект, думай, сколько он будет жить и где разрушаться. Лучше, чтобы создание и разрушение образовывали "скобки" (как бы замыкали код). Везде где можно, используй умные указатели, но помни о циклических ссылках.
Со временем привыкаешь, и такого рода ошибки становятся очень редкими.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)