О распределении памяти и C ++ - PullRequest
3 голосов
/ 13 июня 2010

И я цитирую из MSDN http://msdn.microsoft.com/en-us/library/aa366533(VS.85).aspx:

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

Теперь задайте вопросы:

a) Что мы подразумеваем, что malloc зависит от времени выполнения?Какие функции динамического выделения памяти могут быть независимыми от времени выполнения?Это утверждение звучит очень странно.

b) новое зависит от языка?Конечно, это должно быть правильно?Являются ли HeapAlloc, LocalAlloc и т. Д. Независимыми от языка?

в) С точки зрения чистой производительности предпочтительны ли функции, предоставляемые MSVC?

Arpan

Ответы [ 4 ]

4 голосов
/ 13 июня 2010

Проблемы с malloc и new возникают при использовании DLL.В зависимости от параметров сборки, DLL может иметь свою собственную копию CRT.Это заставляет его использовать собственную кучу для выделения памяти из кучи , отличной от , чем та, которая используется в EXE.Это вызывает сбой, когда память выделяется одним модулем и освобождается другим.Очень часто, когда вы используете STL.

Один из способов решить эту проблему - скомпилировать код с параметром / MD.Это заставляет использовать общую копию CRT, хранящуюся в его собственной DLL.Проблема решена, теперь есть только один распределитель, использующий одну кучу.

Эта проблема также возникает с COM, он позволяет взаимодействовать различным языкам.Конечно, они никогда не будут использовать общий распределитель, так как эти языки имеют разные библиотеки поддержки времени выполнения.По контракту код COM должен использовать один распределитель, предоставляемый поддержкой времени выполнения COM, CoTaskMemAlloc ().

Обратите внимание, что HeapAlloc () не может решить эту проблему.Требуется дескриптор кучи, возвращаемый HeapCreate ().Разные модули должны будут совместно использовать этот дескриптор, чтобы избежать проблем.


Обновление: для адреса в VS2012 CRT теперь выделяет из общей кучи, кучи процесса по умолчанию (функция GetProcessHeap).

1 голос
/ 13 июня 2010

а) В этом случае я думаю, что они переходят из "библиотеки времени выполнения" в "среду выполнения". Другими словами, это зависит от реализации в вашей библиотеке C.

б) Действительно, новшество специфично для C ++. HeapAlloc и т. Д. Технически применимы в C и C ++.

c) Их нельзя использовать для создания объектов C ++, потому что они не будут вызывать конструкторы, поэтому вопрос довольно спорный В C ++ вы должны использовать new и delete.

0 голосов
/ 14 июня 2010

Ничего себе, это любопытное утверждение, которое появляется в документации без сопроводительного объяснения. Может ли это быть с момента появления C ++? Что касается ответов на ваши вопросы, я могу только догадываться:

a) Возможно, они хотят сравнить это с распределением времени ссылки / загрузки, например, для глобальных переменных, констант и данных static. Или, возможно, они хотят противопоставить это выделению стека, например семейству alloca.

b) Возможно, они обращают внимание на тот факт, что вам не следует выделять память с помощью C ++ new, а затем передавать владение этой памятью библиотечной процедуре, которая может free() ее. Таким образом, в этом смысле результат распределения зависит от языка.

в) Используйте C ++ new и delete. Вы должны предположить, что лежащий в основе C ++ распределитель во время выполнения MSVC так же быстр, если не идентичен системным вызовам в стиле C. Просто помните, что new и delete делают больше, чем выделяют и освобождают память. Они не могут быть полностью заменены malloc и free или другими распределителями в стиле C.

0 голосов
/ 13 июня 2010

a) Это означает, что поведение malloc зависит от версии среды выполнения C, с которой вы компилируете.

b) HeapAlloc и LocalAlloc являются функциями Win32 API. Они действительно не зависят ни от времени выполнения, ни от языка.

в) Невозможно ответить, не зная, как реализованы подпрограммы времени выполнения. Я подозреваю, что их производительность сравнима. В любом случае, если вы используете новый оператор, то у вас всегда есть возможность переопределить его позже, если это необходимо. Помните, преждевременная оптимизация - корень всего зла. ;)

Последнее замечание: LocalAlloc и GlobalAlloc имеют значение медленно . Вы не должны использовать их, если это не вызвано жестким старым Win32 API.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...