Что такое код localalloc


Что такое код localalloc

function LocalAlloc(Flags, Bytes: Word): THandle;

Выделяет из локальной кучи память под блок локальной памяти. Фактический pазмеp может быть больше, чем указанный.

Flags: Одна или несколько из следующих констант: lmem_Discardable, lmem_Fixed, lmem_Modify, lmem_Moveable, lmem_NoCompact, lmem_NoDiscard и lmem_ZeroInit. См. pаздел «Флаги локальной памяти, lmem_» в главе 1.
Bytes: Размеp выделяемого блока в байтах.

Идентификатоp выделенного блока локальной памяти; 0 — если ошибка.

Использование LocalAlloc и LocalRealloc

У меня есть приложение Visual Studio 2008 C ++ для Windows Mobile 6, в котором я использую API-интерфейс стиля FindFirst () / FindNext () для получения коллекции элементов. Я не знаю, сколько предметов будет в списке раньше времени. Итак, я хотел бы динамически выделить массив для этих элементов.

Обычно я бы использовал std::vector<> , но по другим причинам это не вариант для этого приложения. Итак, я использую LocalAlloc() и LocalReAlloc() .

Что мне не ясно, так это то, должна ли эта память быть помечена как фиксированная или подвижная. Приложение работает в любом случае. Мне просто интересно, что «правильно».

Редактировать: Ответчики (не без оснований) зацикливаются на использовании LocalAlloc () по сравнению с другими лучшими вариантами. Поэтому я предоставлю больше контекста.

Этот кусок кода выполняется из вызываемой библиотеки RAPI. Итак, в этом контексте это выглядит примерно так:

Приложение должно выделить память для параметра pInput с помощью функции LocalAlloc. Звонящий отвечает за освобождение pInput. Система выделяет память для параметра ppOutput. Когда приложение заполнено буфером, оно должно освободить память с помощью функции LocalFree.

3 ответа

Из того, что я могу сказать, LHND даже не является допустимым флагом для использования в версии LocalAlloc Windows Mobile .

Когда вы вызываете LocalAlloc версию LocalAlloc с LMEM_MOVEABLE , тип возвращаемого значения не INFO_STRUCT* . Тип возвращаемого значения — HLOCAL — дескриптор выделенной памяти. Это не сам указатель, поэтому неправильно разыменовывать его как указатель. Чтобы получить указатель, вам нужно использовать LocalLock чтобы сообщить ОС, что в данный момент она не должна перемещать память.

Флаги подвижной памяти LHND, LMEM_MOVABLE и NONZEROLHND добавляют ненужные издержки и требуют безопасного использования блокировки. Их следует избегать, если в документации не указано, что их следует использовать.

Итак, если вам действительно нужно использовать LocalAlloc , то выделите фиксированную память, а не подвижную. Это то же самое поведение, которое вы получите от вызова простого старого malloc .

Флаг LMEM_MOVEABLE означает что-то другое с LocalReAlloc . Принимая во внимание, что с LocalAlloc это указывает, заблокирована ли память, с LocalReAlloc это указывает, разрешено ли функции перемещать память для удовлетворения запроса на больший блок памяти. Если вы не LocalReAlloc этот флаг в LocalReAlloc , то функция будет ограничена изменением размера блока на месте. Если там нет места, то функция завершится ошибкой, даже если где-то в куче будет больше блоков памяти.

Чтобы получить эффект malloc , вызовите LocalAlloc(LMEM_FIXED) . Чтобы получить эффект realloc , вызовите LocalReAlloc(LMEM_MOVEABLE) . Включите LMEM_ZEROINIT в любом случае, если хотите.

Единственное, что нужно от всего этого избежать, это то, что вы должны использовать только те флаги, которые в документации конкретно указано, что вы можете использовать для каждой функции. Для LocalAlloc не упоминается LMEM_MOVEABLE , а для LocalReAlloc не упоминается LPTR .

Функция LocalAlloc

Описание:

function LocalAlloc(Flags, Bytes: Word): THandle;

Выделяет из локальной кучи память под блок локальной памяти. Фактический pазмеp может быть больше, чем указанный.

Параметры:

Flags: Одна или несколько из следующих констант: lmem_Discardable, lmem_Fixed, lmem_Modify, lmem_Moveable, lmem_NoCompact, lmem_NoDiscard и lmem_ZeroInit. См. pаздел «Флаги локальной памяти, lmem_» в главе 1.
Bytes: Размеp выделяемого блока в байтах.

Возвpащаемое значение:

Идентификатоp выделенного блока локальной памяти; 0 — если ошибка.

GlobalAlloc, HeapAlloc — Как может доступ к другому процессу? Локальная куча — c

Контекст:

У меня возникло такое сомнение при работе над реализацией буфера обмена для 32-битного приложения Windows в API C/Win32.

Как мы знаем, API-интерфейсы Windows classic для буфера обмена ожидают, что мы передадим блок памяти, который должен быть глобальным и общим (чтобы к нему можно было получить доступ через границу процесса). И большинство примеров на MSDN/Web передают ему дескриптор, возвращаемый API GlobalAlloc (..).

Теперь, как указано на MSDN и объяснено RaymondC в его блоге серия:

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

Мое сомнение:

Илон Маск рекомендует:  Отражение по вертикали

Я понимаю, что все это сводится к распределению памяти из локальной кучи процесса. Но я не могу понять, как это будет работать при переключении контекста? Я имею в виду, что существующие PD/PTE процесса будут обновляться до переключения процесса, а затем эти страницы/выделенная память больше не будут указывать на одну и ту же физическую память.

Прежде чем читать MSDN, я предположил, что GlobalAlloc (..) будет выделять память в Kernel Space. Но я все еще не могу понять, как распределяется память.

Связанные с этим сомнения: Кто и когда будет освобожден блок памяти?

Кроме того, было бы очень полезно, если бы кто-то мог указать мне на источник/документы, содержащие немного сложную информацию об этом, чтобы я мог демистифицировать его раз и навсегда.

ВИДЕОКУРС
выпущен 4 ноября!

Описание:
function LocalAlloc(Flags, Bytes: Word): THandle;

Выделяет из локальной кучи память под блок локальной памяти. Фактический pазмеp
может быть больше, чем указанный.

Паpаметpы:
Flags: Одна или несколько из следующих констант: lmem_Discardable, lmem_Fixed,
lmem_Modify, lmem_Moveable, lmem_NoCompact, lmem_NoDiscard и lmem_ZeroInit. См.
pаздел «Флаги локальной
памяти, lmem_» в главе 1.
Bytes: Размеp выделяемого блока в байтах.

Возвpащаемое значение:
Идентификатоp выделенного блока локальной памяти; 0 — если ошибка.

Использование LocalAlloc и LocalRealloc

У меня есть приложение Visual Studio 2008 C ++ Windows Mobile 6, в котором я использую API-интерфейс FindFirst ()/FindNext() для получения коллекции элементов. Я не знаю, сколько предметов будет в списке раньше времени. Поэтому я хотел бы динамически выделять массив для этих элементов.

Normally, I would use a std::vector<> , but, for other reasons, that’s not an option for this application. So, I’m using LocalAlloc() and LocalReAlloc() .

То, что я не понимаю, — это то, что эта память должна быть маркирована фиксированной или подвижной. Приложение работает отлично в любом случае. Мне просто интересно, что правильно.

Изменить: ответчики (не необоснованно) получают зависание при использовании LocalAlloc() над другими лучшими параметрами. Поэтому я предоставил больше контекста.

Этот фрагмент кода выполняется из встроенной DLL-библиотеки RAPI. Таким образом, в этом контексте он выглядит более как это:

Приложение должно выделять память для параметра pInput с помощью функции LocalAlloc. Вызывающий абонент отвечает за освобождение pInput. Система выделяет память для параметра ppOutput. Когда приложение будет заполнено буфером, оно должно освободить память с помощью функции LocalFree.

В чем разница между malloc() и calloc() а также free() и dellete()?

Допустим мы выделаем память

У них есть 2 разницы
calloc выделяет память под массив данных, предварительно инициализируя её нулями. принимает 2 аргумента.
malloc выделяет память без инициализации. принимает один аргумент.

Но в принципе оба эти функций делают одно и тоже, в чем их разница ?
Где то читал что calloc создает ячейки определенного типа и обединяет их, к примеру int может быть 4 байта, и если мы напишем
int *y = (int*) calloc(3, sizeof(int));
То он создаст 12 ячеек, 4 4 4 и в каждом из 4 байтов будет храниться цифра 0.

int *x = (int*) malloc(12);
Тоже создаст 12 ячеек но если к примеру, в него добавим первый 4 байт цифру 9, в другой байт «string», а в другой вообще bool, как он определит что в нем находиться ?

Если в случае с calloc он знает что через каждые 4 байта у него есть цифра, то как в malloc он определит, что через каждые разные количество байтов у него разные количество элементов, Или он определяет свои элементы совсем по другому, в этапе компиляций и т.д.?

  • Вопрос задан более года назад
  • 960 просмотров

Разница только в том, что calloc обнуляет выделенную память перед тем, как возвратить указатель, а malloc этого не делает. Внутри calloc, наверняка вызывает malloc для выделения памяти, а потом memset для обнуления. Так что calloc это просто надстройка над malloc для удобства. Вот схематично реализация calloc:

Сами эти функции оперируют исключительно размером выделяемой области в байтах, им все равно что вы в дальнейшем будете делать с выделенной памятью — инты туда писать или «стринги».
Ну и как бы никто не мешает вам одну и ту же область памяти сначала использовать как массив интов, а потом как массив байт. Или так например:

Пример не использует malloc/calloc для выделения памяти, память выделяется в стеке просто объявлением int a. Тут я попытался показать, что содержимое памяти можно интерпретировать как угодно, главное находится в границах выделенного диапазона.
Причем языки С/С++/asm это позволяют делать, а другие — нет.
Пример предполагает, что int имеет размер 32 бита, не для всех платформ это так, но в основном — именно так.
Кстати этот пример можно использовать для определения порядка байтов платформы: если выведется «1 2 3 4» значит у вас LITTLE ENDIAN, а если «2 1 4 3» — BIG ENDIAN.

Илон Маск рекомендует:  Что такое код sleep

PS: free() — это Си, а delete — C++

А free и delete ведут себя идентично ?
Оба ставят метку на область памяти, и считают эту область мусором или все данные в этой области становятся нулями ?
И еще delete вызывает деструктор, а free нет тогда как он освобождает память ?
В некоторых руководствах пишут, что

Так значит free просто отнимает память ?

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

Для данной конкретной ОС и настроек компилятора по значению this можно предположить где выделена память, но в общем случае — нет. Кроме того, память может быть выделена не для одного объекта (деструктор которого вызван), а для массива объектов. Что вы будете освобождать в этом случае?
Поэтому вызов деструктора в delete здесь не к месту упомянут. И да, в С++ используется именно delete потому что на нем завязана дополнительная функциональность по вызову деструктора.

Да, free просто освобождает память.
Вызов realloc в вашем примере освободит память выделенную для х и вернет нулевой указатель.

Есть некоторое количество разных реализаций менеджеров памяти, которые по разному реализуют malloc/free. В своем проекте вы можете использовать сторонний менеджер памяти, а не тот что предлагается по умолчанию. Кроме того в ОС есть собственный менеджер памяти и можно использовать его. В винде это функции LocalAlloc/LocalFree и еще пачка других.

И еще вот такой вопрос, касательно malloc`a и calloc`

Допустим память выделяется вот так

в calloc храним только Int → 1, 2, 4, 3 каждое из которых 4 байт = 16 байт.
А в malloc храним int 1 → char a, b → double int 5, получается у нас 4байт + 2 + 8 = 14 байт.

Вот как тут компилятор, процессор или не знаю что) понимает что именно находится в этих ячеек ?

Если предположить с логикой, то можно понять что calloc уже знает что через каждые 4 байта у него внутри число типа int. (Я точно не знаю так ли это работает)

Тогда как malloc не знает через сколько шагов что именно у него внутри.

Вот как тут компилятор, процессор или не знаю что) понимает что именно находится в этих ячеек ?

Что такое код localalloc

1) На Раздел распространяются все Правила Форума.
2) Перед тем, как создать новый топик, убедитесь, что Вы читали Правила создания тем в Разделе.
3) Вопросы, не связанные с программированием (настройки MS Visual Studio, книги, библиотеки и т.д.),
обсуждаются в разделе C/C++: Прочее
4) Вопросы разработки .NET (Windows Form, C++/CLI и т.п.) приложений на Visual C++/C# обсуждаются в разделе .NET.
5) Нарушение Правил может повлечь наказание со стороны модераторов.

Здравствуйте.
Столкнулся с такой проблемой — пишу программу на голом WinAPI, и программа работает очень нестабильно — вываливается на вызовах LocalAlloc/GlobalAlloc.
Абстрактный пример:

Я написал примерный образец структуры, как это выглядит. Сама программа очень большая.
Проблема в том, что случайным (?) образом молча вываливается на вызовах GlobalAlloc. Действительно молча — никаких ошибок или сообщений — просто выход из программы. Такое впечатление, что вместо GlobalAlloc компилятор вставляет exit().

Операторы new и delete ипользовать нельзя! Пробывал менять на LocalAlloc/LocalFree — ноль эффекта. Заметил, что место падения зависит от того, сколько памяти было запрошено/освобождено ранее.
Бъюсь над этим уже два дня, никто не знает, в чем может быть проблема? Все классы проверил, везде корректная очистка за собой памяти.
IDE: MS Visual Studio 2005.

LocalAlloc and LocalRealloc usage

I have a Visual Studio 2008 C++ Windows Mobile 6 application where I’m using a FindFirst() / FindNext() style API to get a collection of items. I do not know how many items will be in the list ahead of time. So, I would like to dynamically allocate an array for these items.

Normally, I would use a std::vector<> , but, for other reasons, that’s not an option for this application. So, I’m using LocalAlloc() and LocalReAlloc() .

What I’m not clear on is if this memory should be marked fixed or moveable. The application runs fine either way. I’m just wondering what’s ‘correct’.

Edit: Responders are (not unreasonably) getting hung up on the use of LocalAlloc() over other better options. So I will provide more context.

Илон Маск рекомендует:  Администрирование получаем время с удалённого nt сервера

This chunk of code is being executed from within a RAPI invokable DLL. So, in that context, it looks more like this:

From the CeRapiInvoke() documentation:

An application should allocate memory for the pInput parameter with the LocalAlloc function. The caller is responsible for freeing pInput. The system allocates memory for the ppOutput parameter. When the application is completed with the buffer, it should free the memory with the LocalFree function.

3 Answers 3

From what I can tell, LHND is not even a valid flag to use in the Windows Mobile version of LocalAlloc .

When you call the non-mobile version of LocalAlloc with LMEM_MOVEABLE , the return type is not INFO_STRUCT* . The return type is HLOCAL — a handle to the memory that you’ve allocated. It’s not a pointer itself, so it is incorrect to dereference it like a pointer. To get a pointer, you need to use LocalLock to tell the OS that it mustn’t move the memory around for the time being.

The movable-memory flags LHND, LMEM_MOVABLE, and NONZEROLHND add unnecessary overhead and require locking to be used safely. They should be avoided unless documentation specifically states that they should be used.

So, if you really must use LocalAlloc , then allocate fixed memory, not movable. That’s the same behavior you’d get from calling plain old malloc .

The LMEM_MOVEABLE flag means something different with LocalReAlloc . Whereas with LocalAlloc it specifies whether the memory is locked, with LocalReAlloc it specifies whether the function is allowed to move the memory in order to satisfy a request for a larger block of memory. If you don’t include that flag with LocalReAlloc , then the function is restricted to changing the block’s size in-place. If there’s no room there, then the function will fail, even if there are larger blocks of memory available elsewhere in the heap.

To get the effect of malloc , call LocalAlloc(LMEM_FIXED) . To get the effect of realloc , call LocalReAlloc(LMEM_MOVEABLE) . Include LMEM_ZEROINIT in either case if you wish.

One thing to take away from all this seems to be that you should only use the flags that the documentation specifically says you can use for each function. For LocalAlloc , it doesn’t mention LMEM_MOVEABLE , and for LocalReAlloc , it doesn’t mention LPTR .

Нарушение доступа с помощью LocalAlloc ()

У меня есть приложение Visual Studio 2008 для Windows Mobile 6 C ++, которое использует API, который требует использования LocalAlloc() . Чтобы сделать мою жизнь проще, я создал реализацию стандартного распределителя, который использует LocalAlloc () внутри:

Мое приложение использует эту реализацию распределителя в std :: vector <>

На 257-м элементе, добавленном в вектор <>, приложение вылетает с нарушением прав доступа:

LocalAllocator::allocate вызывается с n=512 и LocalReAlloc() завершается успешно. Фактическое исключение нарушения LocalAllocator::allocate доступа возникает в коде std :: vector <> после LocalAllocator::allocate :

Если кто-нибудь может указать, что я могу делать неправильно, я был бы признателен.

Сначала я подумал, что вашей проблемой является параметр LHND для LocalReAlloc() — обычно вы не должны передавать этот параметр этой функции.

Проблема в том, что вам даже не следует вызывать эту функцию. Реализация vector перераспределяет свою собственную память. Стандартный распределитель C ++ не обеспечивает перераспределение.

Вы должны реализовать:

Нечто подобное должно работать.

Вам не нужно отслеживать указатель — он будет возвращен вам при вызове deallocate() , за который отвечает ваш API-клиент, реализация vector .

Я не уверен, как это должно работать. Когда вы выделяете каждый следующий блок, вы освобождаете текущий используемый блок. Таким образом, все указатели, которые указали там, становятся недействительными. Я сомневаюсь, что это то, что вектор ожидает от распределителя.

Чтобы расширить ответ Игоря Кривокона , каждый вызов allocate() возможно, делает недействительными все указатели, возвращенные предыдущими вызовами allocate() . Это не то, как распределитель должен работать и, скорее всего, приведет к неопределенному поведению:

Например, когда вектору нужно выделить новый больший объем памяти, он скопирует данные из «старой» памяти в «новую», возвращаемую allocate() . Затем он уничтожит все объекты в «старой» памяти и освободит ее.

Если старые и новые теперь являются одними и теми же ячейками памяти, конструкция копирования «новых» объектов и последующее уничтожение «старых» объектов будут испорчены. С другой стороны, если old больше не действителен (потому что он перераспределен), вектор получит доступ к неверной памяти.

И еще один момент: распределители должны быть копируемыми. Если копия создается из вашего распределителя, а затем оба используются для размещения дополнительных элементов, LocalReAlloc() будет вызываться для одного и того же указателя дважды. Поэтому вам нужно будет предоставить собственный конструктор копирования, который позволит избежать подобных проблем.

Понравилась статья? Поделиться с друзьями:
Кодинг, CSS и SQL