Re[3]: Резервирование стека при вызове ф-й
От: Валерий Б. Россия  
Дата: 31.01.03 13:32
Оценка: 9 (1)
Здравствуйте, vasketsov, Вы писали:

V>Здравствуйте, grapes, Вы писали:


G>>пере-х стек перепелнила — такого еще не случалось (на моем веку)

V>Счастливый! (Или молодой? )
V>Переполнение стека — серезная проблема, она существует с самого начала вычислительной техники, ибо стек — это базовая форма хранения данных. Используется кроме всего прочего, из-за огромной скорочти выделения памяти (фактически, она уже выделена, просто указатель сдвигается). Естественно, она виртуальная, других и не бывает на самом деле, просто ее явно обычно не выделяют, поэтому так говорить не принято.
На платформах IBM PC обычно (т.е. в Win) весь стек нити сразу оказывается в виртуальном адресном пространстве процесса. Причем старшая по адресу незаполненная страница памяти имеет флаг PAGE_GUARD, а все остальные незаполненные страницы так вообще процессу не доступны (Access violation), физическая память для них еще не выделена. Когда происходит первое обращение к этой старшей странице, вызывается обработчик, который делает эту страницу доступной, выделяет следующую страницу с младшим адресом и на нее ставит флаг PAGE_GUARD. Этот обработчик можно даже перепрограммировать, но я не пробовал.
Интересно поисследовать, каковы потери в быстродействии из-за этого обработчика.
Интересно, что memcpy заполняет память от младших адресов к старшим. Но вот при использовании ее в конструкторе копирования больших (в несколько страниц) объектов на стеке все работает без Access violation. То есть, прежде чем такой конструктор вызовется, все необходимые страницы памяти под локальные переменные уже будут созданы! Это тоже потеря быстродействия?
Re[6]: Резервирование стека при вызове ф-й
От: Владик Россия  
Дата: 31.01.03 15:04
Оценка: 4 (1)
Здравствуйте, Валерий Б., Вы писали:

В>>А ты (ради интереса) посмотри, что компилятор делает, когда размер локальных переменных переваливает через 4кб

ВБ>И что? Не умею я смотреть, неохота вникать в ассемблер.

А там как раз цикл организуется, который последовательно по 4кб от стэка отъедает.
Как все запущенно...
Re[8]: Резервирование стека при вызове ф-й
От: vasketsov Россия http://ntprog.by.ru
Дата: 31.01.03 15:31
Оценка: 4 (1)
Здравствуйте, Валерий Б., Вы писали:

В>>А там как раз цикл организуется, который последовательно по 4кб от стэка отъедает.

ВБ>Мат-перемат. А разве APIшными функциями ему не быстрее их всех сразу отъесть?
Быстрее. Именно это _chkstk и делает.
Если программа использует RTL из ntdll.dll (у меня многие это делают) и описывается локальная структура больше 4K — эта функция вызывается, именно она все за раз и отъедает, без циклов.
Васкецов Сергей
http://registry.km.ru
Re[3]: Резервирование стека при вызове ф-й
От: mik1  
Дата: 31.01.03 12:53
Оценка: 3 (1)
Здравствуйте, grapes, Вы писали:

G>То есть он считает число локальных переменных в вызываемой ф-ции? Зачем? Они же не в стеке будут размещаться!


А где?

Удалено избыточное цитирование. -- ПК.
Резервирование стека при вызове ф-й
От: grapes  
Дата: 31.01.03 12:44
Оценка: 2 (1)
Когда компилер с++ вызывает ф-цию, он резервирует ей стек:
sub esp, 0x44
после вызова он возвращает указатель обратно.
Вопрос: как он определяет то, на сколько надо сдвинуть стек (почему именно 44?)
Re[8]: Резервирование стека при вызове ф-й
От: Аноним  
Дата: 01.02.03 09:12
Оценка: 2 (1)
Здравствуйте, Валерий Б., Вы писали:

ВБ>Мат-перемат. А разве APIшными функциями ему не быстрее их всех сразу отъесть?


Я тоже задавался этим вопросом Было это давно, и человек с которым я дискутировал как-то это обосновал (а может просто запарил Цикл с отъеданием по 4кб организует борландовский компилятор. С микрософтовским все хитрее. Как уже здесь говорилось он вызывает свою функцию, и кроме того, там в опциях компиляции можно указать размер этих "блоков".

ВБ>А потом вызываются конструкторы в которых уже можно обращаться к любым членам объекта, т.к. они уже в доступной памяти.

ВБ>А в С тоже всегда цикл вызывается? Там ведь уже и компилятору необязательно предварительно странички отъедать, если он сообразит, когда какой объект потребуется, то может соптимизирует это дело.
Re: Резервирование стека при вызове ф-й
От: mik1  
Дата: 31.01.03 12:46
Оценка:
Здравствуйте, grapes, Вы писали:

G>Когда компилер с++ вызывает ф-цию, он резервирует ей стек:

G>sub esp, 0x44
G>после вызова он возвращает указатель обратно.
G>Вопрос: как он определяет то, на сколько надо сдвинуть стек (почему именно 44?)

ИМХО, объем передаваемых переменных + объем локальных переменных.
Re[2]: Резервирование стека при вызове ф-й
От: grapes  
Дата: 31.01.03 12:51
Оценка:
Здравствуйте, mik1, Вы писали:

G>>Вопрос: как он определяет то, на сколько надо сдвинуть стек (почему именно 44?)


M>ИМХО, объем передаваемых переменных + объем локальных переменных.


То есть он считает число локальных переменных в вызываемой ф-ции? Зачем? Они же не в стеке будут размещаться!

Удалено избыточное цитирование. -- ПК.
Re[4]: Резервирование стека при вызове ф-й
От: grapes  
Дата: 31.01.03 12:57
Оценка:
Здравствуйте, mik1, Вы писали:


M>>>ИМХО, объем передаваемых переменных + объем локальных переменных.


G>>То есть он считает число локальных переменных в вызываемой ф-ции? Зачем? Они же не в стеке будут размещаться!


M>А где?


Разве не в обычной памяти?
Re[5]: Резервирование стека при вызове ф-й
От: m.a.g. Мальта http://dottedmag.net/
Дата: 31.01.03 13:01
Оценка:
Здравствуйте, grapes, Вы писали:

G>>>То есть он считает число локальных переменных в вызываемой ф-ции? Зачем? Они же не в стеке будут размещаться!


M>>А где?


G>Разве не в обычной памяти?


А что такое "обычная память"?

Типа "обычного" стирального порошка?
... << silent >> ...
Re: Резервирование стека при вызове ф-й
От: grapes  
Дата: 31.01.03 13:04
Оценка:
Здравствуйте, grapes, Вы писали:

G>Когда компилер с++ вызывает ф-цию, он резервирует ей стек:

G>sub esp, 0x44
G>после вызова он возвращает указатель обратно.
G>Вопрос: как он определяет то, на сколько надо сдвинуть стек (почему именно 44?)


И еще — если бы каждая вызываемая ф-ция размещала бы свои локальные переменные в стеке, то он бы просто лопнул — вот когда происходит глубокая рекурсия (ф-я сама себя вызывает) — это и происходит, а чтобы просто ф-ция с большим к-вом лок. пере-х стек перепелнила — такого еще не случалось (на моем веку)
Re[6]: Резервирование стека при вызове ф-й
От: grapes  
Дата: 31.01.03 13:05
Оценка:
Здравствуйте, m.a.g., Вы писали:

MAG>А что такое "обычная память"?


Динамически выделяемая

Удалено избыточное цитирование. -- ПК.
Re[2]: Резервирование стека при вызове ф-й
От: vasketsov Россия http://ntprog.by.ru
Дата: 31.01.03 13:11
Оценка:
Здравствуйте, grapes, Вы писали:

G>пере-х стек перепелнила — такого еще не случалось (на моем веку)

Счастливый! (Или молодой? )
Переполнение стека — серезная проблема, она существует с самого начала вычислительной техники, ибо стек — это базовая форма хранения данных. Используется кроме всего прочего, из-за огромной скорочти выделения памяти (фактически, она уже выделена, просто указатель сдвигается). Естественно, она виртуальная, других и не бывает на самом деле, просто ее явно обычно не выделяют, поэтому так говорить не принято.
Васкецов Сергей
http://registry.km.ru
Re[2]: Резервирование стека при вызове ф-й
От: Аноним  
Дата: 31.01.03 13:15
Оценка:
Попробуй объяви локальный массив здорового размера — что получится?
Re[2]: Резервирование стека при вызове ф-й
От: m.a.g. Мальта http://dottedmag.net/
Дата: 31.01.03 13:19
Оценка:
Здравствуйте, grapes, Вы писали:

G>И еще — если бы каждая вызываемая ф-ция размещала бы свои локальные переменные в стеке, то он бы просто лопнул — вот когда происходит глубокая рекурсия (ф-я сама себя вызывает) — это и происходит, а чтобы просто ф-ция с большим к-вом лок. пере-х стек перепелнила — такого еще не случалось (на моем веку)


А попробуй поставить стек 4kb и создать локальный массив элементов так из 8000.
... << silent >> ...
Re[7]: Резервирование стека при вызове ф-й
От: m.a.g. Мальта http://dottedmag.net/
Дата: 31.01.03 13:19
Оценка:
Здравствуйте, grapes, Вы писали:

G>>>Разве не в обычной памяти?

MAG>>А что такое "обычная память"?
MAG>>Типа "обычного" стирального порошка?

G>Динамически выделяемая


А какого GUI там переменные должны размещаться? Попробуй каждый раз при вызове функции для всех переменных выделять память используя new, а в конце прибивать delete'ом и посмотри быстродействие.
... << silent >> ...
Re: Резервирование стека при вызове ф-й
От: grapes  
Дата: 31.01.03 13:32
Оценка:
Здравствуйте, grapes, Вы писали:

G>Когда компилер с++ вызывает ф-цию, он резервирует ей стек:

G>sub esp, 0x44
G>после вызова он возвращает указатель обратно.
G>Вопрос: как он определяет то, на сколько надо сдвинуть стек (почему именно 44?)


Все, признаю себя Великим Идиотом...
Re: Резервирование стека при вызове ф-й
От: ilnar Россия  
Дата: 31.01.03 13:38
Оценка:
Здравствуйте, grapes, Вы писали:

G>Когда компилер с++ вызывает ф-цию, он резервирует ей стек:

G>sub esp, 0x44
G>после вызова он возвращает указатель обратно.
G>Вопрос: как он определяет то, на сколько надо сдвинуть стек (почему именно 44?)

если я не ошибабсь, компилятор оставляет специальное пространство для проверки, нет ли нарушей границ стека, причем инициализирует специальными символами.
Re[2]: Резервирование стека при вызове ф-й
От: grapes  
Дата: 31.01.03 13:49
Оценка:
Здравствуйте, ilnar, Вы писали:

I>если я не ошибабсь, компилятор оставляет специальное пространство для проверки, нет ли нарушей границ стека, причем инициализирует специальными символами.


Абсолютно верно.
Стек он забивает 0xCC, а после вызова ф-ции смещает указатель стека назад и смотрит, равен ли он тому, что было до вызова

Удалено избыточное цитирование. -- ПК.
Re[3]: Резервирование стека при вызове ф-й
От: vasketsov Россия http://ntprog.by.ru
Дата: 31.01.03 13:55
Оценка:
Здравствуйте, grapes, Вы писали:

G>Стек он забивает 0xCC

В Debug-версии.
Васкецов Сергей
http://registry.km.ru
Re[4]: Резервирование стека при вызове ф-й
От: vasketsov Россия http://ntprog.by.ru
Дата: 31.01.03 14:02
Оценка:
Здравствуйте, Валерий Б., Вы писали:

ВБ>а все остальные незаполненные страницы так вообще процессу не доступны (Access violation), физическая память для них еще не выделена.

Здесь обычно используется термин "передача", а не "выделение".

ВБ>Этот обработчик можно даже перепрограммировать, но я не пробовал.

Примеры этого есть.

ВБ>Интересно поисследовать, каковы потери в быстродействии из-за этого обработчика.

Никто не запрещает сразу "закоммитить" весь стек.
В этом случае, кстати, последняя страница сторожевой не будет.
Васкецов Сергей
http://registry.km.ru
Re[4]: Резервирование стека при вызове ф-й
От: Владик Россия  
Дата: 31.01.03 14:07
Оценка:
Здравствуйте, Валерий Б., Вы писали:

>использовании ее в конструкторе копирования больших (в несколько страниц) объектов на стеке все работает без Access violation. То есть, прежде чем такой конструктор вызовется, все необходимые страницы памяти под локальные переменные уже будут созданы! Это тоже потеря быстродействия?


А ты (ради интереса) посмотри, что компилятор делает, когда размер локальных переменных переваливает через 4кб
А после этого можно будет поспорить по поводу того, что всегда ли "динамическое" выделение памяти будет медленне "стэкового"
Как все запущенно...
Re[3]: Резервирование стека при вызове ф-й
От: DemAS http://demas.me
Дата: 31.01.03 14:12
Оценка:
Здравствуйте, vasketsov, Вы писали:


V>Переполнение стека — серезная проблема,

[...]
mik1> ИМХО, объем передаваемых переменных + объем локальных переменных.
[...]

Прошу прощения, но я не понимаю, как может переполнится стек, учитывая сказанное mik1. Если не сложно, поясните.
... <<Наслаждаюсь — The Razors Edge>>
Re[4]: Резервирование стека при вызове ф-й
От: Stanislav Kondratiev  
Дата: 31.01.03 14:33
Оценка:
Здравствуйте, vasketsov, Вы писали:

V>Здравствуйте, grapes, Вы писали:


G>>Стек он забивает 0xCC

V>В Debug-версии.
И проверки тоже в Debug версии.
Причем MSVC++ 6 в Дебаг-версии всегда восстанавливает стек при выходе из функции, поэтому если ты где-то напортачил внутри — то этого можешь даже и не заметить, а в релизе обязательно вылетит — у меня так было.
Re[2]: Резервирование стека при вызове ф-й
От: comer США http://getboost.codeplex.com/
Дата: 31.01.03 14:44
Оценка:
Здравствуйте, grapes, Вы писали:

G>И еще — если бы каждая вызываемая ф-ция размещала бы свои локальные переменные в стеке, то он бы просто лопнул — вот когда происходит глубокая рекурсия (ф-я сама себя вызывает) — это и происходит, а чтобы просто ф-ция с большим к-вом лок. пере-х стек перепелнила — такого еще не случалось (на моем веку)


Тебе вопрос, если бы даже место под локальные переменные выделялось в динамической памяти, где должны храниться указатели на эти пременные?
getboost.codeplex.com
citylizard.codeplex.com
Re[5]: Резервирование стека при вызове ф-й
От: Валерий Б. Россия  
Дата: 31.01.03 14:57
Оценка:
Здравствуйте, Владик, Вы писали:

В>А ты (ради интереса) посмотри, что компилятор делает, когда размер локальных переменных переваливает через 4кб

И что? Не умею я смотреть, неохота вникать в ассемблер.
В>А после этого можно будет поспорить по поводу того, что всегда ли "динамическое" выделение памяти будет медленне "стэкового"
Так я и не спорю. Хотелось бы выяснить велики ли эти потери, да никак руки не доходят.
Re[6]: Резервирование стека при вызове ф-й
От: vasketsov Россия http://ntprog.by.ru
Дата: 31.01.03 15:15
Оценка:
Здравствуйте, Валерий Б., Вы писали:

В>>А ты (ради интереса) посмотри, что компилятор делает, когда размер локальных переменных переваливает через 4кб

ВБ>И что? Не умею я смотреть, неохота вникать в ассемблер.

Может использоваться _chkstk.
Васкецов Сергей
http://registry.km.ru
Re[7]: Резервирование стека при вызове ф-й
От: grapes  
Дата: 31.01.03 15:18
Оценка:
Здравствуйте, vasketsov, Вы писали:

V>Здравствуйте, Валерий Б., Вы писали:


В>>>А ты (ради интереса) посмотри, что компилятор делает, когда размер локальных переменных переваливает через 4кб

ВБ>>И что? Не умею я смотреть, неохота вникать в ассемблер.

V>Может использоваться _chkstk.



Там юзается _chkesp
Re[7]: Резервирование стека при вызове ф-й
От: Валерий Б. Россия  
Дата: 31.01.03 15:22
Оценка:
Здравствуйте, Владик, Вы писали:

В>Здравствуйте, Валерий Б., Вы писали:


В>>>А ты (ради интереса) посмотри, что компилятор делает, когда размер локальных переменных переваливает через 4кб

ВБ>>И что? Не умею я смотреть, неохота вникать в ассемблер.

В>А там как раз цикл организуется, который последовательно по 4кб от стэка отъедает.

Мат-перемат. А разве APIшными функциями ему не быстрее их всех сразу отъесть?
А потом вызываются конструкторы в которых уже можно обращаться к любым членам объекта, т.к. они уже в доступной памяти.
А в С тоже всегда цикл вызывается? Там ведь уже и компилятору необязательно предварительно странички отъедать, если он сообразит, когда какой объект потребуется, то может соптимизирует это дело.
Re[3]: Резервирование стека при вызове ф-й
От: MaximE Великобритания  
Дата: 31.01.03 15:26
Оценка:
Здравствуйте, vasketsov, Вы писали:


V>Переполнение стека — серезная проблема, она существует с самого начала вычислительной техники, ибо стек — это базовая форма хранения данных.


Offtopic.
Базовых форм две: массив и список. Стэк может быть релизован либо как первое, либо как второе — больше никак.
Re[8]: Резервирование стека при вызове ф-й
От: Znow  
Дата: 31.01.03 15:33
Оценка:
Здравствуйте, Валерий Б., Вы писали:

ВБ>Здравствуйте, Владик, Вы писали:


В>>Здравствуйте, Валерий Б., Вы писали:


В>>А там как раз цикл организуется, который последовательно по 4кб от стэка отъедает.

ВБ>Мат-перемат. А разве APIшными функциями ему не быстрее их всех сразу отъесть?

При размере стека потока в 1 Мб такое передвижение "шажками" за время его жизни произойдет не более, чем 256 раз. Не страшно.
Re[4]: Резервирование стека при вызове ф-й
От: vasketsov Россия http://ntprog.by.ru
Дата: 31.01.03 15:33
Оценка:
Здравствуйте, MaximE, Вы писали:

ME>Базовых форм две: массив и список.

Гы. А также LIFO и FIFO. И что?
Васкецов Сергей
http://registry.km.ru
Re[9]: Резервирование стека при вызове ф-й
От: vasketsov Россия http://ntprog.by.ru
Дата: 31.01.03 15:36
Оценка:
Здравствуйте, Znow, Вы писали:

Z>При размере стека потока в 1 Мб такое передвижение "шажками" за время его жизни произойдет не более, чем 256 раз.

Да? А обосновать?
Или по вашему стек только расти может?
Васкецов Сергей
http://registry.km.ru
Re[10]: Резервирование стека при вызове ф-й
От: Znow  
Дата: 31.01.03 15:56
Оценка:
Здравствуйте, vasketsov, Вы писали:

Z>>При размере стека потока в 1 Мб такое передвижение "шажками" за время его жизни произойдет не более чем 256 раз.

V>Да? А обосновать?
V>Или по вашему стек только расти может?

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

Т. к. обычный размер зарезервированного под стек ВАП в 1 МБ на Интеловской архитектуре равен 256 страницам, то такая передача произойдет не более чем 256 раз. Если она произойдет в 257 раз, то это уже будет переполнение стека.
Re[11]: Резервирование стека при вызове ф-й
От: vasketsov Россия http://ntprog.by.ru
Дата: 31.01.03 16:09
Оценка:
Здравствуйте, Znow, Вы писали:

Z>Если же и такое бывает (хотя до такого терроризма додуматься трудно), то, конечно, приведенное выше мое утверждение неверно.


Хорошо, пусть есть функция, в которой выделяется в стеке 100-килобайтная структура.
Я могу эту функцию вызвать 10 раз — и все, приплыли?
Васкецов Сергей
http://registry.km.ru
Re[12]: Резервирование стека при вызове ф-й
От: Znow  
Дата: 01.02.03 12:51
Оценка:
Здравствуйте, vasketsov, Вы писали:

Z>>Если же и такое бывает (хотя до такого терроризма додуматься трудно), то, конечно, приведенное выше мое утверждение неверно.


V>Хорошо, пусть есть функция, в которой выделяется в стеке 100-килобайтная структура.

V>Я могу эту функцию вызвать 10 раз — и все, приплыли?

Если там 10 уровней рекурсии, — то да, приплыли.

Если 10 раз последовательно, то, ясное дело, передача страничной памяти, если и будет выполняться, то лишь в первый раз. В остальное время охранная страница будет уже отодвинута достаточно далеко, чтобы не быть достигнутой. Соответственно, указатель вершины стека будет бугать туда-сюда в рамках пространства стека, под которое страничная память уже передана.
Re[13]: Хотелось бы получить ответ
От: Znow  
Дата: 04.02.03 07:06
Оценка:
Взаимное недопонимание устранено или я в чем-то заблуждаюсь?

Очень неприятно ошибаться и не знать этого. Так что хотелось бы получить ответ.
Re[14]: Хотелось бы получить ответ
От: vasketsov Россия http://ntprog.by.ru
Дата: 04.02.03 17:42
Оценка:
Здравствуйте, Znow, Вы писали:

Z>Взаимное недопонимание устранено или я в чем-то заблуждаюсь?

Да нет, видимо, о разных вещах говорим.
Я утверждал, что текущее положение в стеке откатывается, ты — что вершина не откатывается.
И то и другое одновременно, очевидно, может реализовываться.
Правда, то что память не освобождается — ничуть не очевидно.
Зато дизассемблирование _chkstk дает много поучительной имформации.
Васкецов Сергей
http://registry.km.ru
Re[15]: Хотелось бы получить ответ
От: Znow  
Дата: 04.02.03 17:46
Оценка:
Здравствуйте, vasketsov, Вы писали:

V>Я утверждал, что текущее положение в стеке откатывается, ты — что вершина не откатывается.


Я такое говорил? Где?
Re[16]: Хотелось бы получить ответ
От: vasketsov Россия http://ntprog.by.ru
Дата: 04.02.03 19:27
Оценка:
Здравствуйте, Znow, Вы писали:

Z>Я такое говорил? Где?


Пара постов вверх.
Опять же, под вершиной РАЗНОЕ может быть понято, видишь как легко флейм провоцировать?
Большинство считает, что вершина стека — это его текущее положение, исторически так принято.
В данном случае реально вершина болтается где-то посредине между вершиной в смысле переданой памяти и базового адреса стека.
Вот и все, а ты испугался.
Васкецов Сергей
http://registry.km.ru
Re[5]: Резервирование стека при вызове ф-й
От: Magister Россия  
Дата: 05.02.03 00:32
Оценка:
Здравствуйте, Владик, Вы писали:

В>Здравствуйте, Валерий Б., Вы писали:


>>использовании ее в конструкторе копирования больших (в несколько страниц) объектов на стеке все работает без Access violation. То есть, прежде чем такой конструктор вызовется, все необходимые страницы памяти под локальные переменные уже будут созданы! Это тоже потеря быстродействия?


В>А ты (ради интереса) посмотри, что компилятор делает, когда размер локальных переменных переваливает через 4кб

В>А после этого можно будет поспорить по поводу того, что всегда ли "динамическое" выделение памяти будет медленне "стэкового"

Это верно, при больщой глубине появляются тормоза.
Я это встретил при разработке парсеров. Избавился от рекурсии и получил свои ~ 20 метров в сек.

Нужно стараться решать проблему рекурсии переработкой алгоритма, и держать по меньше
больших обьектов в стэке.
Re[5]: Резервирование стека при вызове ф-й
От: Magister Россия  
Дата: 05.02.03 01:15
Оценка:
Здравствуйте, Stanislav Kondratiev, Вы писали:

SK>Здравствуйте, vasketsov, Вы писали:


V>>Здравствуйте, grapes, Вы писали:


G>>>Стек он забивает 0xCC

V>>В Debug-версии.
SK>И проверки тоже в Debug версии.
SK>Причем MSVC++ 6 в Дебаг-версии всегда восстанавливает стек при выходе из функции, поэтому если ты где-то напортачил внутри — то этого можешь даже и не заметить, а в релизе обязательно вылетит — у меня так было.

У теня тоже. Это легко достигнуть подсовывая в MESSAGE MAP MFC функцию не правильного прототипа.
в дебаге работает, в релизе ...
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.