Что такое код locallock


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

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

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

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

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

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

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

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

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

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

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

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

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

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

Ошибка CLOCK_WATCHDOG_TIMEOUT как исправить

Во время работы с ОС Windows пользователь может столкнуться с зависанием системы, а затем и появлением «синего экрана смерти» (BSoD), в тексте которого упомянута ошибка «CLOCK_WATCHDOG_TIMEOUT». Обычно данная ошибка имеет аппаратную природу, сигнализируя о проблемах с «железом» пользовательского ПК. В данном материале я расскажу, что за ошибка CLOCK_WATCHDOG_TIMEOUT, каковы её причины, и как исправить ошибку данную проблему на вашем компьютере.

Разберёмся с причинами ошибки CLOCK_WATCHDOG_TIMEOUT

В переводе текст данной ошибки звучит что-то вроде «время ожидания контроля истекло» и обычно обозначает ситуацию, когда ожидаемое временное прерывание на вторичном процессоре в мультипроцессорной системе не было получено в течение выделенного временного интервала.

Проще говоря, какой-либо процессор (или ядро многоядерного процессора) не отвечает на запросы системы по различным причинам.

В большинстве случаев рассматриваемая ошибка имеет именно аппаратную природу. Что относится ко всей полноты вызывающих её причин, то я бы выделил следующие:

  • Пользовательский разгон системы (оверклокинг);
  • Нестабильная работа планок памяти ПК;
  • Проблема в работе графической карты (в частности, конфликт между дискретной и встроенной графической картой компьютера);
  • Проблемы с драйверами (некорректные, устаревшие, повреждённые драйвера);
  • Реестр ОС Виндовс повреждён по различным причинам;
  • Злокачественная деятельность вирусных программ;
  • Проблемы в работе жёсткого диска (множество «битых» секторов);
  • Нарушение целостности системных файлов;
  • Недавняя установка на компьютер проблемного приложения (устройства), работающего не корректно.

Ошибка на Windows

Как исправить ошибку CLOCK_WATCHDOG_TIMEOUT

Для решения проблемы CLOCK_WATCHDOG_TIMEOUT советую выполнить следующее:

  1. Перейдите в БИОС и сбросьте его настройки по умолчанию;
  2. Откажитесь от разгона системы (оверклокинга), отмените все соответствующие настройки вашей системы;
  3. Отключите функции C1E и Intel Speedstep в БИОСе;
  4. Если у вас в системе две видеокарты (одна дискретная и одна встроенная), и вы пользуетесь дискретной, тогда отключите встроенную видеокарту в БИОСе вашего ПК;
  5. Обновите драйвера системных устройств до самых свежих версий. В частности, в этом поможет функционал специализированных программ уровня DriverPack Solution, Driver Genius и других аналогов;

Используйте DriverPack Solution для обновления драйверов

  • Используйте функционал системной утилиты SFC для проверки целостности системных файлов. Запустите командную строку от имени администратора, там введите:
  • sfc /scannow — и нажмите ввод. Дождитесь окончания проверки, перезагрузите систему и проверьте, будет ли появляться рассматриваемая ошибка.

    Выполняем sfc /scannow

    • Проверьте системный реестр на ошибки с помощью соответствующих программ (CCleaner, RegCleaner и других аналогов);
    • Выполните проверку системы на наличие вирусов (помогут антивирусные инструменты Dr.Web CureIt!, Malwarebytes Anti-Malware, Trojan Remover и другие аналоги);
    • Удалите антивирус Avast с системы. В ряде случаев появление данной ошибки было обусловлено работой указанной антивирусной программы. Попробуйте удалить данную программу из системы, а затем понаблюдать над стабильностью работы вашего ПК;

    Удалите Avast с системы

  • Удалите Daemon Tools lite. Та же ситуация;
  • Если вы недавно установили какую-либо новую программу, попробуйте (хотя бы временно) деинсталлировать её с ПК, вполне возможно, что причиной ошибки CLOCK_WATCHDOG_TIMEOUT был именно данный программный продукт;
  • Временно отключит ваш антивирус и брандмауэр, чтобы определить, не являются ли данные инструменты причиной рассматриваемой дисфункции;
  • Откатите систему на временную точку, при которой рассматриваемой проблемы не наблюдалось. Нажмите кнопку «Пуск», в строке поиска введите rstrui и нажмите ввод. Поищите стабильную точку восстановления и откатите систему к данному состоянию;

    Попробуйте восстановление системы

  • Проверьте корректность работы памяти компьютера с помощью программы Memtest86;
  • Проверьте жёсткий диск на наличие плохих секторов (к примеру, с помощью функционала программы Victoria или команды CHKDSK);
  • Попробуйте обновить ваш БИОС (рекомендуется для компетентных пользователей);
  • Заключение

    Появление ошибки CLOCK_WATCHDOG_TIMEOUT может иметь множество причин, при этом большинство из них обычно имеют аппаратную природу. Рекомендую, прежде всего, отказаться от оверклокинга и сбросить настройки БИОС до базовых значений – часто эти советы оказывались наиболее эффективными. Если же данные способы не помогли, воспользуйтесь другими, перечисленными выше, советами, это позволит исправить ошибку CLOCK_WATCHDOG_TIMEOUT на вашем ПК.

    Ошибка CLOCK_WATCHDOG_TIMEOUT в Windows 10

    Одна из самых сложных в определении причин и исправлении ошибок в Windows 10 — синий экран «На вашем ПК возникла проблема и его необходимо перезагрузить» и код ошибки CLOCK_WATCHDOG_TIMEOUT, который может появляться как в произвольные моменты, так и при выполнении определенных действий (запуск конкретной программы, подключение устройства и т.п.). Сама по себе ошибка говорит о том, что ожидаемое системой прерывание не было получено с одного из ядер процессора за ожидаемое время, что, как правило, мало говорит о том, что делать дальше.

    В этой инструкции — о наиболее распространенных причинах ошибки и способах исправить синий экран CLOCK_WATCHDOG_TIMEOUT в Windows 10, если это возможно (в некоторых случаях проблема может быть аппаратной).

    Синий экран смерти (BSoD) CLOCK_WATCHDOG_TIMEOUT и процессоры AMD Ryzen

    Решил вынести информацию об ошибке применительно к владельцам компьютеров на Ryzen в отдельный раздел, поскольку для них, помимо причин, описанных далее есть и свои специфичные.

    Итак, если у вас на борту установлен CPU Ryzen, и вы столкнулись с ошибкой CLOCK_WATCHDOG_TIMEOUT в Windows 10, рекомендую учесть следующие моменты.

    1. Не устанавливайте ранние сборки Windows 10 (версии 1511, 1607), поскольку в них возможны конфликты при работе на указанных процессорах, что приводит к ошибкам. В дальнейшем были устранены.
    2. Обновите БИОС вашей материнской платы с официального сайта её производителя.

    По второму пункту: на ряде форумов сообщают, что, наоборот, ошибка проявляется после обновления БИОС, в данном случае срабатывает откат на предыдущую версию.

    Проблемы с БИОС (UEFI) и разгон

    Если в последнее время вы меняли параметры БИОС или выполняли разгон процессора, это может служить причиной ошибки CLOCK_WATCHDOG_TIMEOUT. Попробуйте следующие шаги:

    1. Отключить разгон процессора (если выполнялся).
    2. Сбросить БИОС на настройки по умолчанию, можно — оптимизированные настройки (Load Optimized Defaults), подробнее — Как сбросить настройки БИОС.
    3. Если проблема появилась после сборки компьютера или замены материнской платы, проверьте, есть ли на официальном сайте производителя обновление БИОС для неё: возможно, проблема была решена в обновлении.

    Проблемы с периферийным оборудованием и работой драйверов

    Следующая по распространенности причина — неправильная работа оборудования или драйверов. Если вы недавно подключили новое оборудование или же только что переустановили (обновили версию) Windows 10, обратите внимание на следующие методы:

    1. Установите оригинальные драйверы устройств с официального сайта производителя вашего ноутбука или материнской платы (если это ПК), особенно драйверы чипсета, USB, управления электропитанием, сетевых адаптеров. Не используйте драйвер-паки (программы для автоматической установки драйверов), также не воспринимайте серьезно «Драйвер не нуждается в обновлении» в диспетчере устройств — это сообщение не говорит о том, что новых драйверов действительно нет (их нет лишь в центре обновлений Windows). Для ноутбука также следует установить вспомогательное системное ПО, также с официального сайта (именно системное, различные прикладные программы, которые также могут там присутствовать не обязательны).
    2. В случае, если в диспетчере устройств Windows есть устройства с ошибками, попробуйте отключить их (правый клик мышью — отключить), если это новые устройства, то можно отключить их и физически) и перезагрузить компьютер (именно перезагрузка, а не завершение работы с последующим включением, в Windows 10 это может быть важно), а затем понаблюдать — проявляется ли проблема снова.

    Еще один момент, касающийся оборудования — в некоторых случаях (речь о ПК, не ноутбуках) проблема может проявляться при наличии двух видеокарт на компьютере (интегрированного чипа и дискретной видеокарты). В БИОС на ПК обычно присутствует пункт для отключения интегрированного видео (как правило, в разделе Integrated Peripherals), попробуйте выполнить отключение.

    Программное обеспечение и вредоносные программы

    Помимо прочего, BSoD CLOCK_WATCHDOG_TIMEOUT может быть вызвана недавно установленными программами, особенно теми из них, которые работают с Windows 10 на низком уровне или добавляют свои системные службы:

    1. Антивирусы.
    2. Программы, добавляющие виртуальные устройства (можно посмотреть в диспетчере устройств), например, Daemon Tools.
    3. Утилиты для работы с параметрами БИОС из системы, например, ASUS AI Suite, программы для разгона.
    4. В некоторых случаях — софт для работы с виртуальными машинами, например, VMWare или VirtualBox. Применительно к ним, иногда ошибка возникает в результате неправильной работы виртуальной сети или при использовании специфичных систем в виртуальных машинах.

    Также к такому ПО можно отнести вирусы и другие вредоносные программы, рекомендую выполнить проверку компьютера на их наличие. См. Лучшие средства удаления вредоносных программ.

    Ошибка CLOCK_WATCHDOG_TIMEOUT как следствие аппаратных проблем

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

    1. Перегрев, пыль в системном блоке. Следует почистить компьютер от пыли (даже при отсутствии признаков перегрева это не будет лишним), при перегреве процессора, возможно, также поменять термопасту. См. как узнать температуру процессора.
    2. Неправильная работа блока питания, напряжения отличные от требуемых (можно отследить в БИОС некоторых материнских плат).
    3. Ошибки оперативной памяти. См. Как проверить оперативную память компьютера или ноутбука.
    4. Проблемы с работой жесткого диска, см. Как проверить жесткий диск на ошибки.

    Более серьезные проблемы этого характера — неисправности материнской платы или процессора.

    Дополнительная информация

    Если ничто из описанного пока не помогло, возможно, могут оказаться полезными следующие пункты:

    • Если проблема возникла недавно, а система не переустанавливалась, попробуйте использовать точки восстановления Windows 10.
    • Выполните проверку целостности системных файлов Windows 10.
    • Часто проблема бывает вызвана работой сетевых адаптеров или их драйверов. Иногда не удается точно определить, что дело в них (обновление драйверов не помогает и т.п.), но, при отключении компьютера от Интернета, выключении Wi-Fi адаптера или вынимании кабеля из сетевой карты проблема исчезает. Это не обязательно говорит о проблемах именно сетевой карты (также могут быть виноваты системные компоненты, неправильно работающие с сетью), но может помочь в диагностике проблемы.
    • Если ошибка проявляется при запуске какой-то конкретной программы, возможно, проблема вызвана именно её некорректной работой (возможно, конкретно в этой программной среде и на этом оборудовании).

    Надеюсь, один из способов поможет решить проблему и в вашем случае ошибка не вызвана аппаратными проблемами. Для ноутбуков или моноблоков с оригинальной ОС от производителя вы также можете попробовать выполнить сброс на заводские настройки.

    Почему она называется Marshal.AllocHGlobal, если он выделяет на локальной куче?

    AllocHGlobal является одним из двух методов выделения памяти в классе Marshal. Этот метод предоставляет функцию Win32 LocalAlloc от Kernel32.dll.

    Учитывая , что есть GlobalAlloc API , который выделяет память на глобальной куче, а не локальной кучи, не имя этого метода достаточно ввести в заблуждение?

    Была ли причина назвать его AllocHGlobal , а не AllocHLocal ?

    Обновление: Саймон указывает в комментариях , что нет такого понятия , как глобальная кучи в Windows , больше, а GlobalAlloc и LocalAlloc интерфейсы остались только унаследованных целей. В эти дни, GlobalAlloc API ничего Morethan обертка для LocalAlloc .

    Это объясняет , почему API не вызывает GlobalAlloc у всех, но это не объясняет , почему API был назван , AllocHGlobal когда он не дает (не может) использовать глобальную кучу, и даже не звонить GlobalAlloc . Именование не может быть для устаревших причинам, так как он не был введен до .NET 2.0, путь после 16-битная поддержка была сброшена. Таким образом, остается открытым вопрос: почему Marshal.AllocHGlobal так обманчиво назвали?

    Предположим , что вы делаете передачу данных между приложениями с помощью перетаскивания или через буфер обмена. Для заполнения STGMEDIUM структуры вам нужно HGLOBAL . Таким образом , вы звоните AllocHGlobal . Отсюда и название.

    Основное применение для этой функции является Interop с API , которые хотят иметь HGLOBAL . Было бы запутанным , если его называли что — нибудь еще , потому что , когда вы хотели HGLOBAL вы должны найти некоторые документы , чтобы сказать вам , что AllocAnythingElse произвел значение , которое вы могли бы использовать в качестве HGLOBAL .

    Это восходит к стародавним временам Windows, версии 3. Тогда было понятие «по умолчанию кучи», функция апи GlobalAlloc (), выделенная из него. Память, выделенная из этой кучи может быть разделена между всеми процессами.

    Все изменилось в 32-разрядной версии Windows, процессы больше не могут разделять память через кучу. Какие из терминов «глобальная куча» и «локальная куча» бессмысленно. Существует еще понятие кучи по умолчанию, в «куче процесса». GlobalAlloc () теперь выделяет из этой кучи. Но это не может быть разделено между границами процесса. Фактическая реализация GlobalAlloc, и Marshal.AllocHGlobal, использует функцию апи LocalAlloc (). Другой Windows, 3 пережиток, несколько более подходящее имя для того, что происходит в эти дни. Это, в свою очередь, использует HeapAlloc () с GetProcessHeap () на 32-битной Windows.

    Соглашаясь на куче, чтобы использовать значительное Interop беспокойство. Это очень часто идет не так в плохо написанном коде C, что вы PInvoke. Любой такой код, который возвращает указатель на выделенную память, которая должна быть выпущена вызывающей часто выходит из строя из-за утечки памяти или нарушение прав доступа. Такой C код выделяет из своей собственной кучи с помощью функции таНоса (). Какая частная куча создана библиотека времени выполнения. У вас нет надежды выпускать такую ​​память, вы не знаете, что куча была использована и нет никакого способа, чтобы получить дескриптор CRT кучи.

    Это может прийти только к хорошему концу, когда код C использует хорошо известную кучу. Как и куча процесса. Или CoTaskMemAlloc (), используемый COM кода. Другой один в классе маршала. Обратите внимание, что PInvoke маршаллер всегда освобождает память при необходимости с CoTaskMemFree (). Это Kaboom на Vista, и, если эта память не была выделена с CoTaskMemAlloc (), бесшумные утечки на XP.

    Короткая часть его:


    Глобальные и локальные функции памяти На первый взгляд кажется, что локальные и глобальные функции управления памятью существуют в Windows, исключительно для обратной совместимости с ОС Windows версии 3.1. Это может быть правдой, но функции управляются так же эффективно, как новые функции кучи, обсуждаемых ниже. На самом деле, перенос приложения с 16-разрядной Windows, не обязательно включает в себя миграцию из глобальных и локальных функций памяти для кучи функций памяти. Глобальные и локальные функции предлагают одни и те же основные возможности (и затем некоторые из них), а так же быстро работать. Во всяком случае, они, вероятно, более удобно работать, потому что вы не должны следить за кучную ручку.

    Тем не менее, реализация этих функций не является таким же, как это было для 16-битной Windows. 16-битная ОС Windows была глобальной куча, и каждое приложение имело локальную кучу. Эти две кучи менеджеров реализовали глобальные и локальные функции. Выделение память с помощью GlobalAlloc означает извлечение блока памяти из глобальной кучи, в то время как LocalAlloc выделенной памяти из локальной кучи. Windows, в настоящее время имеет одну кучу для обоих типов функций-кучи по умолчанию, описанных выше.

    Теперь вы, вероятно, интересно, если есть какая-то разница между самими местными и глобальными функциями. Ну, ответ нет, они сейчас же. На самом деле, они являются взаимозаменяемыми. Память, выделенная через вызов LocalAlloc может быть перераспределена с GlobalReAlloc, а затем заперт LocalLock. В следующей таблице перечислены глобальные и локальные функции теперь доступны.

    Это кажется излишним иметь два набора функций, которые выполняют точно так же, но вот где обратная совместимость приходит. Если вы использовали глобальные или локальные функции в 16-разрядное приложение Windows, до того не имеет значения, теперь они одинаково эффективны ,

    Также память была очень дорогой в те дни. Также обратите внимание на PostScript Language Reference Manual, которые могут дать вам хорошее представление об использовании локальной / глобальной памяти.

    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.

    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 .

    Что такое код locallock

    Каков правильный порядок их вызова? Т.е. (как я понимаю):
    1. LocalAlloc
    2. LocalLock
    3. LocalUnlock
    4. LocalFree

    Делаю LocalAlloc, потом еще раз LocalAlloc (другой размер памяти) — и все работает. Так и должно быть? Или вроде как ф-ция должна возвращать nil, если память по этому указателю уже выделена? Зачем тогда LocalReAlloc?
    И вот еще, LocalFree не освобождает указатель, пока не напишешь прямо — hMem:=nil

    Знаю, щас пошлют в Яндекс или Гугл. Был уже.


    > Или вроде как ф-ция должна возвращать nil, если память по
    > этому указателю уже выделена?

    По какому такому «этому указателю» ?
    Среди параметров LocalAlloc() нет никаких указателей ..


    > Зачем тогда LocalReAlloc?

    Вот как раз LocalReAlloc() и принимает параметром тот самый указатель, который был возвращен одним из предшествующих вызовов LocalAlloc().


    > LocalFree не освобождает указатель, пока не напишешь прямо
    > — hMem:=nil

    Ну это очевидная ерунда.


    > Среди параметров LocalAlloc() нет никаких указателей ..

    Она возвращает the return value is the handle of the newly allocated memory object. Это указатель на выделеную память, так?

    > Это указатель на выделеную память, так?

    Ну так, и?


    > Это указатель на выделеную память, так?

    Нет, не так. Handle — это не указатель. Кроме того, заметь, возвращает, а не получает.

    Указатель же на блок выделенной памяти возвращает ф-ция LocalLock(), получающая параметром тот самый хэндл, возвращенный ф-цией LocalAlloc().

    пишу такое:

    // указатель
    var
    Str: LPTSTR;

    // выделяем память
    Str:=LPTSTR(LocalAlloc(LPTR, 3));

    // Записываем туда че-нибудь
    Str:=»123″;

    // Проверяем
    if (Str<>nil) then . — оно не равно nil, почему?

    Если без LocalFree написать Str:=nil, а потом снова Str:=LPTSTR(LocalAlloc(LPTR, 22)); — все работает, выделяет 22 символа

    > [3] evvcom © (16.06.06 11:48)
    Оп-с. Конечно же, Handle не указатель.


    > Оп-с. Конечно же, Handle не указатель.

    Ну да Бог с ним, с указателем. Просто очень хочеться понять как должно это все работать ПРАВИЛЬНО, у меня работает так как мне нужно, даже больше :) но подозреваю что могут быть проблемы вроде утечки памяти и т.п.

    Есть ли необходимость использовать именно эти функции?
    Почему бы не применять более удобные дельфийские?
    (если не идет работа с API-функциями, требующими именно указанные методы работы с памятью)

    > Просто очень хочеться понять как должно это все работать
    > ПРАВИЛЬНО

    Посмотри LocalLock. Она принимает HLOCAL и возвращает нужный тебе указатель


    > max999 (16.06.06 11:51) [5]


    > // Освобождаем
    > LocalFree(LocalHandle(Str));
    >
    > // Проверяем
    > if (Str<>nil) then . — оно не равно nil, почему?

    Кто-то где-то обещал, что функции освобождения памяти обниляют указатели?

    > Если без LocalFree написать Str:=nil, а потом снова Str:
    > =LPTSTR(LocalAlloc(LPTR, 22)); — все работает, выделяет
    > 22 символа

    Код пионэра, приводящий к утечкам памяти.
    PS. Может попросишь воспитательницу книжку-какую по основам прочитать для вас.

    var
    hMem: THandle;
    Str: PChar;
    ..

    hMem := LocalAlloc(LPTR, 3);
    Win32Check(hMem <> 0);

    Str := LocalLock(hMem);
    Win32Check(Assigned(Str));
    try
    ..
    finally
    LocalUnlock(hMem);
    end;

    hMem := LocalReAlloc(hMem, LPTR, 22);
    Win32Check(hMem <> 0);

    Str := LocalLock(hMem);
    Win32Check(Assigned(Str));
    try
    ..
    finally
    LocalUnlock(hMem);
    end;


    > Код пионэра, приводящий к утечкам памяти.

    От их то и не хочеться :)


    > От их то и не хочеться

    Так правило-то одно — «Взял, попользовал, верни на место».

    Подскажите еще, как имея
    hMem: THandle;
    Str: PChar;
    Проверить что это в данный момент используеться? hMem<>nil ?


    > max999 (16.06.06 12:14) [14]
    > Подскажите еще, как имея
    > hMem: THandle;
    > Str: PChar;
    > Проверить что это в данный момент используеться? hMem<>nil?

    Если Вы эти переменные в программе описали, то Вы их в программе используете, если Вы их в программе не используете, то в процессе компиляции Вам будет выдано сообщение, если конечно сообщения не отключены в настройках компилятора.

    Если уж приспичило, то

    try
    Win32Check(LocalSize(hMem) <> 0);
    ShowMessage(«Используется»);
    except
    ShowMessage(«Не используется»);
    end;

    Хотя способ этот неприкрыто дилетантский — просто не теряй хэндл, тогда и проверять ничего не потребуется.

    ———-offtopic
    MBo © (16.06.06 11:59) [8]
    Борис, традиция пятничных задачек канула в небытиё? есть желание 2-3 часа напрячь извилины

    После Unlock и Free LocalSize(hMem) не равно 0
    :»-(
    Знаю что я уже надоел, но программа показывает что оно не равно нулю! Может у меня Дельфя неправильная?

    И еще, я выделил памяти на 3 символа, попробовал записать туда 22 — получилось :) И прочиталось на ура! Разве так должно быть??

    > max999

    var
    str: PChat;
    begin
    str := nil;
    try
    GetMem(str, iSize);
    .
    finally
    if str <> nil then
    FreeMem(str);
    end;
    end;
    не удивлюсь что это будет работать быстрее, чем прямое использование API.
    и зачем себе лишних проблем создавать.

    > [19] max999 (16.06.06 12:37)


    > И еще, я выделил памяти на 3 символа, попробовал записать
    > туда 22 — получилось

    только не удивляйся потом, если программа в самых неожиданных местах будет AV выдавать.. и это только в лучшем случае. В худшем — промолчит.

    Не работает. LocalUnlock возвращает 0.
    Дайте хоть ссылку на работающий пример. Можна на С++.

    >default © (16.06.06 12:21) [17]
    ОК, через полчасика сделаю, только контролировать ветку особо не смогу.


    > max999 (16.06.06 12:37) [19]
    > И еще, я выделил памяти на 3 символа, попробовал записать
    > туда 22 — получилось :) И прочиталось на ура! Разве так
    > должно быть??

    Выдели памяти на твои 3 символа и сразу выдели ещё памяти, после записи 22 символов в первую область, прочитай данные из второй.

    Использование 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 даже недопустимый флаг для использования в версии Windows Mobile LocalAlloc ,

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

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

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

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

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

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

    Со страницы вы ссылаетесь на ваш комментарий к ответу miked

    «В линейной среде Windows Embedded CE API нет разницы между локальной кучей и глобальной кучей. LocalAlloc эквивалентно HeapAlloc(GetProcessHeap, …).»

    Нажав на ссылку, перейдите на CE 6.0 (или Win Mobile 6.0), и вы увидите то же самое.

    Фактически, neww/malloc и т. Д. Все равно сводятся к HeapAlloc внутри. Так что я действительно не уверен, что проблема только с использованием среды выполнения C/C++.

    Из этой ссылки доктора Доббса сказано:

    Использование LocalAlloc и LocalReAlloc таким способом выявило причуду в реализации Windows CE. В прошлом, когда я использовал их в цикле, подобном этому, в NT, я использовал LPTR в качестве флага для LocalReAlloc, что позволило мне выделить до 512 КБ. В Windows CE этот сценарий никогда не выделяет более одного КБ. Это ограничение по размеру слишком мало даже для нашего списка процессов. Изменение флага LocalReAlloc на LMEM_MOVEABLE работает как для NT, так и для CE и позволяет распределять память до размера самого большого свободного блока, поскольку местоположение можно перемещать после вызова LocalAlloc, а не расширять его на месте.

    Atomic Alarm Clock 6.3 + код активации

    Atomic Alarm Clock – это такое интересное и удобное приложение, которое нужно, чтобы проводить замену часов на панели задач, которые выступают стандартными. Программка совсем простая и не требует для своей функциональности огромных системных требований. С ней сможет справиться как опытный пользователь, так и юзер, что только начал познавать компьютерный мир. Данное приложение отменно работает с различными ОС Виндовс, в том числе подходит для Windows 10.

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

    Пароль ко всем архивам: 1progs

    Что относительно интерфейса этого приложения:

    • простой;
    • понятный;
    • настраивается быстро;
    • есть разнообразные интересные темы для оформления.

    В утилите также имеется календарь. Помимо этого пользователь может использовать функцию синхронизации времени через непосредственно Интернет.

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

    Аналоги программы

    Похожие программы смотрите в наших подборках программ

    Использование 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.

    Прочитайте онлайн СПРАВОЧНИК ПО WinAPI | LocalLock

    Описание: function LocalLock(Mem: THandle): Pointer;

    Блокиpует Mem и увеличивает его счетчик захватов. Блок не может быть пеpемещен или уничтожен.

    Паpаметpы:

    Mem: Идентификатоp блока локальной памяти.

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

    В случае успешного завеpшения — указатель на блок, nil — в пpотивном случае. функция находится в файле kernel32.dll

    Внимание!

    Текст предназначен только для предварительного ознакомительного чтения.

    Публикация данных материалов не преследует за собой никакой коммерческой выгоды.

    Эта книга способствует профессиональному росту читателей и является рекламой бумажных изданий.

    Все права на исходные материалы принадлежат соответствующим
    организациям и частным лицам.

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