понедельник, 5 октября 2009 г.

В чём был смысл флага GMEM_SHARE?

Это перевод What was the point of the GMEM_SHARE flag? Автор: Реймонд Чен.

У функции GlobalAlloc есть флаг GMEM_SHARE. Для чего он нужен?

В 16-ти битных Windows флаг GMEM_SHARE контролировал, может ли память пережить выход из процесса, который её выделил. По-умолчанию, вся память, выделяемая процессом, автоматически освобождалась, когда процесс завершался.

Передача же флага GMEM_SHARE подавляла эту автоматическую очистку. Вот почему вам нужно указывать этот флаг при выделении памяти, передаваемую в буфер обмена, или когда вы передаёте её через OLE другому процессу. Поскольку буфер обмена существует и после выхода из вашей программы, все данные, что вы поместили в буфер обмена, должны существовать после вашего выхода. Если вы не указывали этот флаг, то если ваша программа выходила, память, которую вы отдали буферу обмена, очищалась, что приводило к вылету (crash) при первой же попытке обращения к данным, что лежали в буфере обмена.

(Флаг GMEM_SHARE также контролировал, может ли память быть освобождена другим процессом, а не тем, что выделил её. Это имеет смысл для вышеназванной семантики).

Заметьте, что правило очистки применяется к глобальной памяти, выделенной в DLL, от имени процесса. Разработчики DLL должны быть осторожны и отслеживать, была ли вот эта конкретная память специфичной для процесса (и она будет освобождена при его выходе) или же она предназначена для чего-то, что DLL планировала разделять между процессами для своих собственных нужд (и в этом случае она не освобождается при выходе). Невыполнение этого разграничения приводит к багам типа вот этого.

Слава богу, что всё это ушло навсегда с приходом Win32.

2 комментария:

  1. На странице есть опечатка: "Передача же флага GMEM_SHARE поавляла..." - "подавляла"

    ОтветитьУдалить

Можно использовать некоторые HTML-теги, например:

<b>Жирный</b>
<i>Курсив</i>
<a href="http://www.example.com/">Ссылка</a>

Вам необязательно регистрироваться для комментирования - для этого просто выберите из списка "Анонимный" (для анонимного комментария) или "Имя/URL" (для указания вашего имени и ссылки на сайт). Все прочие варианты потребуют от вас входа в вашу учётку (поддерживается OpenID).

Пожалуйста, по возможности используйте "Имя/URL" вместо "Анонимный". URL можно просто не указывать.

Ваше сообщение может быть помечено как спам спам-фильтром - не волнуйтесь, оно появится после проверки администратором.