LocalAlloc Vs GlobalAlloc Vs malloc Vs new

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

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

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

Сравнение методов распределения памяти

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

Функция malloc имеет недостаток, зависящий от времени выполнения. Оператор new имеет недостаток: зависит от компилятора и зависит от языка

Ответы

Ответ 1

Выдержки из Рэймонд Чен OldNewThing

Еще во времена 16-битной Windows разница была значительной.

В 16-битной Windows доступ к памяти осуществлялся через значения, называемые "селекторами", каждое из которых могло адресовать до 64 КБ. Был селектор по умолчанию, называемый "селектор данных"; операции над так называемыми "ближними указателями" были выполнены относительно селектора данных. Например, если у вас был ближний указатель 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. Но функции локальной кучи и функции глобальной кучи, тем не менее, являются двумя различными интерфейсами кучи.

Также указанная вами ссылка ясно говорит о том, что

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

Если вы не понимаете, что такое Malloc vs new, ответ Billy ONeal достаточно ясно это объясняет.

Для различия между malloc и HeapAlloc, Дэвид Хеффернан и Луис Мигель Хуапайя ответ вместе дает идеальное решение:

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

Ответ 2

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

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

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

Ответ 3

Вкратце, LocalAlloc выделит память в локальной куче процесса. В то время как GlobalAlloc использует системную кучу.

Ниже приведены различия между malloc() и оператором new:

  1. Вызов конструкторов: new вызовы конструкторов, в то время как malloc() - нет. На самом деле примитивные типы данных (char, int, float т.д.) Также могут быть инициализированы с новыми. Например, ниже программа печатает 10.

#include<iostream> 

using namespace std; 

int main() 
{ 
   int *n = new int(10); // initialization with new() 
   cout << *n; 
   getchar(); 
   return 0; 
} 
  1. оператор против функции: new является оператором, а malloc() является функцией.
  2. тип возвращаемого значения: new возвращает точный тип данных, а malloc() возвращает void *.
  3. Условие сбоя: в случае сбоя malloc() возвращает NULL, где в качестве новых Throws.
  4. Память: в случае нового память выделяется из свободного хранилища, где, как и в malloc() выделение памяти выполняется из кучи.
  5. Переопределение: нам разрешено переопределять новый оператор, поскольку мы не можем переопределить функцию malloc() легально.
  6. Размер: Требуемый размер памяти рассчитывается компилятором для нового, где мы должны вручную рассчитать размер для malloc().