2015-12-17 6 views
15

Я искал это по различным ссылкам, но все же сомнения сохраняются.LocalAlloc Vs GlobalAlloc Vs malloc Vs new

Я не понимаю разницы между LocalAlloc и GlobalAlloc против malloc против new для распределения памяти.

Я прошел через эту ссылку на MSDN:

Comparing Memory Allocation Methods

Пожалуйста, объясните следующее заявление:

таНоса функции имеет тот недостаток, что во время выполнения зависимых. новый оператор имеет тот недостаток, что компилятор зависит и зависит от языка

+0

'LocalAlloc' и' LocalFree' полезны, когда вам необходимо выделить память в одном модуле (DLL или EXE) и отпустить его в отдельном модуле. Если вы не свяжете оба модуля с одним и тем же набором DLL MSVCRT, вызов 'free' или' delete', скорее всего, потерпит крах, поскольку память была malloc'd другим экземпляром среды выполнения. Имея «LocalFree», если часто это простой рассказ для поставщиков API, если они не хотят напрямую открывать функцию deallocate. – selbie

ответ

14

Выдержки из Raymond Chen's OldNewThing

Назад в дни 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. Но локальные функции кучи и глобальные функции кучи - это, тем не менее, два разных интерфейса кучи.

Кроме того, link указанный вами ясно говорит, что

Начиная с 32-битной Windows, GlobalAlloc и LocalAlloc являются реализованы как функции-оболочки, которые требуют HeapAlloc используя дескриптор по умолчанию процесса в heap и HeapAlloc могут быть проинструктированы об освобождении исключения, если память не может быть выделена, возможность не доступна с LocalAlloc.

Для вашего замешательства на таНос против нового, ответ Билли ONeal обобщает, что довольно ясно.

Для разности между malloc and HeapAlloc, Дэвид Heffernan х и ответ Луис Мигель Huapaya в сочетании дает идеальное решение ::

  • malloc является портативным, часть стандарта. malloc (и другие функции кучи времени выполнения C) зависят от модуля, а это означает, что если вы вызываете malloc в коде из одного модуля (то есть в DLL), тогда вы должны позвонить free в код того же модуля или вы можете пострадать от довольно плохой кучи коррупция.
  • HeapAlloc не является переносным, это функция Windows API.Используя HeapAlloc с GetProcessHeap вместо malloc, включая перегрузку new и delete операторов, чтобы использовать их, позволяют передавать динамически выделенные объекты между модулями и не беспокоиться о повреждении памяти, если память выделяется в коде одного модуля и освобождается кодом другого модуля, когда указатель на блок памяти передан во внешний модуль.
+0

Я думаю, что это хорошая статья (в конце концов, я связался с ней примерно за 7 минут до вас отправил этот ответ), но я не думаю, что он отвечает на вопрос пользователя, который конкретно говорит о языке «зависящий от времени» и «компилятор и язык, зависимый». –

+0

Конечно, ваш ответ суммирует все. Я только что поставил четкие, релевантные и короткие отрывки из этого блога. – Abhineet

+0

нет, я не думаю, что блог отвечает на вопрос пользователя. Блог о Global/LocalAlloc. Вопрос пользователя о malloc и новее, о котором в статье ничего не сказано. –

11

GlobalAlloc and LocalAlloc are old functions from the 16 bit era. Разница в том, что иногда вы должны были быть в состоянии выделить память используется только в своем сегменте (который используется рядом указателей), а иногда требуется для распределения памяти для совместного использования с другими процессами и сегментами в системе. Сегодня эти ребята в той или иной форме переходят в функции HeapXxx, такие как HeapAlloc. Если вы пишете новый код и не должны связываться со временем выполнения C, вы должны использовать функции HeapXxx. Конечно, если вы вызовете любой из них, ваша программа будет компилироваться и запускаться только в Windows.

malloc «зависит от времени выполнения», поскольку для его использования требуется привязка к времени выполнения C (CRT). CRT - это библиотека, которая содержит все другие стандартные функции библиотеки C, такие как printf или qsort. Вы можете написать обычную программу Win32 API, не связывая ее с этим (но я, честно говоря, не понимаю, почему вы хотите сделать это в реальном программном обеспечении).

new зависит от компилятора и зависит от языка, поскольку им требуется компилятор, который может скомпилировать C++. (И обычно new реализуется через malloc, так что, вероятно, потребует использования CRT, а)

+0

Спасибо Billy ONeal :). – User1234

+0

'новый' может бросить исключения. Обработка исключений требует CRT при компиляции с Visual Studio (и некоторыми другими компиляторами). Так что даже если 'new' не были реализованы с точки зрения' malloc', вы все равно должны были бы зависеть от CRT. – IInspectable

+0

@ Необычайно не обязательно; пользователь может переопределить новый параметр 'terminate()' при сбое распределения. –