Страница 1 из 3

FreeMem

СообщениеДобавлено: 07.12.2020 19:08:32
Seenkao
Как я понимаю, после очистки памяти, я должен увидеть на тех местах "обнулённую" информацию?
Почему я вижу на этом месту кучу одинакового хлама? Как мне проверить, очистилась или нет эта память? :?:

Re: FreeMem

СообщениеДобавлено: 07.12.2020 19:35:49
Awkward
FreeMem высвобождает память, а не очищает её.

Re: FreeMem

СообщениеДобавлено: 07.12.2020 19:41:31
Seenkao
получается я вижу одну и ту же точку после освобождения памяти? На которую "указывает" "освобождённая" память?

Re: FreeMem

СообщениеДобавлено: 07.12.2020 20:09:29
zub
после освобождения считай там мусор, не нули

Re: FreeMem

СообщениеДобавлено: 07.12.2020 20:23:45
Seenkao
Seenkao писал(а):кучу одинакового хлама?
Я про то, что там постоянно хлам "одинаковый". Одни и те же числа.

Re: FreeMem

СообщениеДобавлено: 07.12.2020 20:28:16
скалогрыз
Seenkao писал(а):Я про то, что там постоянно хлам "одинаковый". Одни и те же числа.

это вопрос везения.
Вовремя самой очистки, таже самая память может быть переиспользована. И то, что в какой-то конкретный момент времени ты видишь там "одни и те же числа", не означает, что ты их же увидишь в какой-то другой момент, или на другой конфигурации.
Сделал FreeMem - всё! забудь об участке памяти, он уже не тот.

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

Re: FreeMem

СообщениеДобавлено: 07.12.2020 20:29:36
Seenkao
Всех благодарю! Понял. А то подумал, что память не очищается.

Re: FreeMem

СообщениеДобавлено: 07.12.2020 20:33:14
скалогрыз
Seenkao писал(а):Всех благодарю! Понял. А то подумал, что память не очищается.

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

По-этому, при "освобождении" памяти, традиционно её не зануляют!
но, в наши дни, кое где, её могут занулять даже принудительно. (ну чтобы пароли в памяти процесса не залежались)

Естественно, в FPC можно назначть собственный менеджер памяти, который будет память занулять.
Таким путём часто идут и при отладке тоже. (например чтобы поймать неверный поинтер раньше)
Подменой менеджера памяти пользуется тот же heaptrc, чтобы явно считать ссылки.

Re: FreeMem

СообщениеДобавлено: 07.12.2020 20:42:39
Seenkao
Хорошо, хотел ещё узнать.
Мы объявляем процедуру/функцию. Даём ей ссылку. Эту ссылку мы так же должны обнулить? Или она автоматически будет обнулена по закрытию программы?

Re: FreeMem

СообщениеДобавлено: 07.12.2020 21:16:33
скалогрыз
Seenkao писал(а):Мы объявляем процедуру/функцию. Даём ей ссылку. Эту ссылку мы так же должны обнулить?

да
Seenkao писал(а):Или она автоматически будет обнулена по закрытию программы

нет

Re: FreeMem

СообщениеДобавлено: 07.12.2020 21:24:36
Pavia
Seenkao писал(а):Хорошо, хотел ещё узнать.
Мы объявляем процедуру/функцию. Даём ей ссылку. Эту ссылку мы так же должны обнулить? Или она автоматически будет обнулена по закрытию программы?

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

Re: FreeMem

СообщениеДобавлено: 07.12.2020 21:31:18
Seenkao
Понял, пробелы будут устранены. Значит как обычно не надо ориентироваться на "большинство". И странно, что этого не делают довольно часто используемые проекты.

Re: FreeMem

СообщениеДобавлено: 07.12.2020 21:36:29
runewalsh
скалогрыз писал(а):Рабочий алгоритм не должен основыватся на содержимом освобождённой памяти.

Вот кстати, бывают низкоуровневые фишки, типа MEM_RESET_UNDO в API VirtualAlloc.

Представь, что ты делаешь графический редактор с возможностью, как водится, многоуровневой отмены операций.
Чтобы не держать всё в памяти, старые версии записываются во временный файл.
После записи на память, хранившую старую версию, делается RESET — чтобы сказать системе, что она нам больше не нужна, и при необходимости она может её спокойно выбросить.

По Ctrl-Z мы пытаемся сделать RESET_UNDO.
Успех RESET_UNDO означает, что система ещё не выгрузила RESET'нутую память и теперь полностью восстановила её содержимое, так что мы можем взять старую версию оттуда, а не подгружать из файла.

Re: FreeMem

СообщениеДобавлено: 07.12.2020 22:39:11
скалогрыз
runewalsh писал(а):Вот кстати, бывают низкоуровневые фишки, типа MEM_RESET_UNDO в API VirtualAlloc.

MEM_RESET_UNDO сработает только, если куски памяти выделенной и освобождённой раньше остались целыми.

допустим, код в редакторе попытался, сделать MEM_RESET_UNDO, но тот вернул ошибку.
Что должен сделать редактор? проигнорировать то, что ему сказал VirtualAlloc и придолжить использовать старый поинтер? или всё-таки загрузить из файла?
Рабочий алгоритм не должен основыватся на содержимом освобождённой памяти.


В частном случае: MEM_RESET не является полным аналогом освобждения памяти, как её понимает FreeMem();
По сути MEM_RESET можно считать полным аналогом, в том случае, когда MEM_RESET_UNDO не смог сделать это самое UNDO :)

Re: FreeMem

СообщениеДобавлено: 08.12.2020 00:15:32
runewalsh
скалогрыз писал(а):Что должен сделать редактор?

Редактор сбрасывает данные, которые «может быть, когда-нибудь понадобятся» (здесь — данные для Ctrl-Z), во временный файл, и затем RESET'ает их в памяти.
Если эти данные понадобились — делает RESET_UNDO.

Если RESET_UNDO сработал, мы можем не читать их из файла, тем самым экономя время и I/O. Если не сработал — что ж, читаем из файла.

Заточка под сценарий, что нам эти данные так никогда и не понадобятся (пользователь не сделает 20 Ctrl-Z подряд). Выбрасывая память, мы снижаем её объём, занимаемый процессом (физически). Если свободной памяти и так предостаточно, RESET'нутые страницы окажутся нетронутыми и система сможет их вернуть, и, наоборот, если памяти впритык, RESET'нутые страницы переиспользуют другие приложения без необходимости системе выгружать в своп их старое содержимое.