Назад в дни 16-битной Windows, разница была значительной ,
В 16-разрядной версии Windows доступ к памяти осуществлялся с помощью значений, называемых «селекторы», каждый из которых мог адресовать до 64K. Был выбран селектор по умолчанию , называемый «селектором данных»; операции с так называемым «около указателей» выполнялись относительно селектора данных. Например, для , если у вас был указатель p, значение которого было 0x1234, а ваш селектор данных был 0x012F, то при написании * p вы получали доступ к памяти в 012F: 1234. (Когда вы объявляли указатель, он был рядом по умолчанию Вы должны были сказать FAR явно, если вы хотите, дальний указатель.).
Важно: Рядом указатели всегда относительны к селектору, обычно селектор данных.
Функция GlobalAlloc назначила селектор, который может использоваться для , чтобы получить доступ к объему запрашиваемой памяти.Вы можете получить доступ к памяти в этом селекторе с «дальним указателем». «Дальний указатель» - это селектор в сочетании с ближайшим указателем. (Помните, что вблизи указателя относительно селектора, когда вы объединяете ближний указатель с соответствующим селектором, вы получаете дальний указатель.)
Каждый экземпляр программы и DLL получила свой собственный селектор данных, известный как HINSTANCE. Поэтому, если у вас был указатель p и получил доступ к , он через * p из исполняемого файла программы, он обратился к памяти относительно HINSTANCE экземпляра программы. Если вы получили доступ к нему из DLL, вы получили память относительно вашего DLL-файла HINSTANCE.
Таким образом, в 16-битной Windows функции LocalAlloc и GlobalAlloc были совершенно разными! LocalAlloc вернул указатель около , тогда как GlobalAlloc вернул селектор.
Указатели, которые вы планировали передать между модулями, должны были быть в форме «дальних указателей» , потому что каждый модуль имеет другой переключатель по умолчанию . Если вы хотите передать владение памятью другому модулю , вам нужно было использовать GlobalAlloc, поскольку это позволило получателю позвонить GlobalFree, чтобы освободить его.
Даже в Win32 вы должны быть осторожны, чтобы не путать местную кучу с глобальной кучей. Память, выделенная из одного, не может быть освобождена на другом . Все странности о ближних и дальних указателях исчезли с перехода на Win32. Но локальные функции кучи и глобальные функции кучи - это, тем не менее, два разных интерфейса кучи.
'LocalAlloc' и' LocalFree' полезны, когда вам необходимо выделить память в одном модуле (DLL или EXE) и отпустить его в отдельном модуле. Если вы не свяжете оба модуля с одним и тем же набором DLL MSVCRT, вызов 'free' или' delete', скорее всего, потерпит крах, поскольку память была malloc'd другим экземпляром среды выполнения. Имея «LocalFree», если часто это простой рассказ для поставщиков API, если они не хотят напрямую открывать функцию deallocate. – selbie