Форум программистов, компьютерный форум, киберфорум
C/C++: WinAPI
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.84/25: Рейтинг темы: голосов - 25, средняя оценка - 4.84
144 / 28 / 4
Регистрация: 06.05.2019
Сообщений: 1,839
Записей в блоге: 4

Посоветуйте функцию для с++ для ОС Windows7 которая может просить память из кучи она должна быть ниже new или maloc

24.10.2020, 22:12. Показов 5518. Ответов 34
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Я хочу написать свой алгоритм распределения памятью, есть свои идеи которые не реализованы в таких функциях как new и других которые содержаться в STL, мне нужна функция которая будет запрашивать сырую память из кучи, и даже было бы хорошо если это память не будет инициализирована а будет поставлена в сыром виде как есть. Посоветуйте что-нибудь такое.
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
24.10.2020, 22:12
Ответы с готовыми решениями:

Батарейка для биоса должна быть аккумуляторной или обычной?
Сдохла батарейка, биос не держит настройки, в связи с чем задаю этот вопрос.

Память не может быть Written или Read
При работе приложений (Фотошоп, плееров, игр) периодично выскакивают таблички: Ошибка приложения. Инструкция ___ обратилась к...

Написать функцию, которая динамически выделит память для полей в структуре
Доброго времени Уважаемые Гуру! Вопрос такой: Нужно сделать функцию которая динамически выделит память для полей в структуре. Вот...

34
Модератор
2131 / 1000 / 170
Регистрация: 23.07.2018
Сообщений: 3,349
Записей в блоге: 3
25.02.2021, 19:58
Студворк — интернет-сервис помощи студентам
Все гигабайты виртуального адресного пространства у каждого процесса свои. Свои таблицы соответствия страниц физической памяти в машине и виртуального адресного пространства процесса. ОС также помнит, из какого места какого файла можно прочитать данные или инструкции, содержащиеся в странице виртуального пространства процесса ( и куда сохранить изменённые данные, если в физической памяти выполняющемуся процессу они пока не нужны ).
Т.о. по одним и тем же виртуальным адресам в одном процессе может вообще ничего не быть, в другом - зарезервированное, но неиспользуемое пространство, в третьем - одна страница физической памяти, в четвёртом - другая, в пятом - страница из DLL, отсутствующая в физической памяти. А одна и та же страница физической памяти может быть расположена сразу по нескольким виртуальным адресам в одном процессе, и по другим - в остальных процессах.
"Рабочие наборы" в Подробностях "Диспетчера задач" - это физические страницы, которые в данный момент используются процессом.

Если сами напишете realloc(), можете написать функцию, проверяющую, есть ли место для увеличения региона. Если есть какой-то HeapWalk, можно и с "чужим" realloc'ом сделать то же самое. Но для этого придётся частично выполнить аналог realloc() (до увеличения размера).
0
144 / 28 / 4
Регистрация: 06.05.2019
Сообщений: 1,839
Записей в блоге: 4
25.02.2021, 22:12  [ТС]
Цитата Сообщение от politoto Посмотреть сообщение
Но для этого придётся частично выполнить аналог realloc()
Просто я не доверяю некоторым функцуиям которые может использовать realloc(), к самой же HeapAlloc() у меня вопросов не возникает, тут по ходу нужно опускаться ещё ниже HeapAlloc и собирать запрос памяти у системы своими алгоритмами, а на это к сожалению нет времени пока что, такие функции мне предлагали но я с ними не разобрался до конца не хватает информации.

Добавлено через 4 минуты
Цитата Сообщение от politoto Посмотреть сообщение
Все гигабайты
Как узнать сколько максимум памяти может выделить HeapAlloc()?
0
Модератор
2131 / 1000 / 170
Регистрация: 23.07.2018
Сообщений: 3,349
Записей в блоге: 3
26.02.2021, 06:27
А сколько может потребоваться?
Самый простой и эффективный способ запросить память у системы -- объявить в своей программе большой статический неинициализированный массив (или несколько массивов) и потом динамически нарезать из него куски требуемого размера своими средствами.
С malloc()/HeapAlloc() тоже можно так сделать ( вообще не вызывать HeapFree() или вызывать один раз при завершении процесса). Но тогда всё равно будут накладные расходы на управление кучей.
0
144 / 28 / 4
Регистрация: 06.05.2019
Сообщений: 1,839
Записей в блоге: 4
26.02.2021, 06:47  [ТС]
Цитата Сообщение от politoto Посмотреть сообщение
Самый простой и эффективный способ запросить память у системы -- объявить в своей программе большой статический неинициализированный массив
ну можно конечно, но речь идёт именно о том что память должна быть динамической, чтобы в случаях когда используешь не всю другие программы могли её тоже брать. В любом случае не понятно сколько максимум памяти можно выделить ни сразу ни в нужный момент времени, хотелось бы знать конечно чтобы правильно всё настроить и по возможности иметь возможность захватить большой кусок.
0
Модератор
2131 / 1000 / 170
Регистрация: 23.07.2018
Сообщений: 3,349
Записей в блоге: 3
26.02.2021, 12:59
Если процесс никак не использует страницы, выделенные загрузчиком для массива ( не читает и не изменяет страницы), то и физическая память для них не используется.
C
1
2
3
4
5
6
7
8
#include <stdio.h>
 
char bytes[ 2000000000 ]; /* ограничение MSVC */
 
int main()
{
    return getchar();
}
(64-разрядный процесс)
Windows Batch file
1
tasklist /FI "IMAGENAME eq t.exe"
Code
1
2
3
Имя образа                     PID Имя сессии          № сеанса       Память
========================= ======== ================ =========== ============
t.exe                         8560 Console                    1     3 144 КБ
А когда понадобится страницы физической памяти, супервизор отберёт их у процесса, не спрашивая.

Если же не хочется даже резервировать место "в файле подкачки", то можно зарезервировать сплошной участок с помощью VirtualAlloc(), но коммитать его только по pagefault'ам при первой попытке обращения к выделенной странице.

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

Добавлено через 9 минут
Ограничение MSVC для массива фактически около 02'00000'00000 - 1000

Добавлено через 27 минут
Цитата Сообщение от Nexi99 Посмотреть сообщение
А есть возможность узнать что сделает realloc() изменит границу массива/блока или перенесёт его в новое место и вернуть к примеру флаг какой-нибудь?
В майкрософтовской библиотеке есть нестандартная функция _expand(), которая никогда не перемещает.
https://docs.microsoft.com/ru-... nce/expand
0
144 / 28 / 4
Регистрация: 06.05.2019
Сообщений: 1,839
Записей в блоге: 4
26.02.2021, 19:50  [ТС]
Цитата Сообщение от politoto Посмотреть сообщение
Если процесс никак не использует страницы, выделенные загрузчиком для массива
Да но процесс не может заранее знать будут они использованы или нет, отсюда возникает противоречие. И как оно это определяет если участок не инициализирован то можно не давать память даже если клиент её запросил. Нельзя точно сказать при запросе большого участка будет ли он использоваться весь, поэтому я и рассматриваю работу с динамической памятью.
Цитата Сообщение от politoto Посмотреть сообщение
В майкрософтовской библиотеке есть нестандартная функция _expand()
да но есть и realloc(), который тоже делает что-то подобное.
При создании кучи всё равно отдаётся страница на 4096 байт. Дело в том что если бы я собрал функции выделения памяти начиная с самого низа то они бы были очень развиты и я бы знал как они работают и сделал бы их быстрее а так не понятно насколько быстро HeapAlloc(),при выделении нового блока копирует данные и многое другое.
0
Модератор
2131 / 1000 / 170
Регистрация: 23.07.2018
Сообщений: 3,349
Записей в блоге: 3
27.02.2021, 14:13
Ни процесс, ни кто-либо ещё не могут в общем случае знать, понадобится ли вызвать ту или иную функцию из того или иного модуля.
Поэтому нет никакого смысла заранее копировать в RAM весь код и даные из файлов EXE и DLL. Физическая память для страницы, содержащей код функции, при необходимости выделится при попытке вызова этой функции процессом. И, рано или поздно, освободится, если ни один процесс этод код больше не использует, а страница физической памяти, например, понадобилась зачем-то другой программе.
То же самое и с данными. Неважно, располагаются ли они в программных секциях или сегментах DLL, стеках, кучах, или каких-то других файлах, спроецированных по запросу программы в адресное пространство процесса.
0
144 / 28 / 4
Регистрация: 06.05.2019
Сообщений: 1,839
Записей в блоге: 4
27.02.2021, 15:31  [ТС]
Цитата Сообщение от politoto Посмотреть сообщение
Ни процесс, ни кто-либо ещё не могут в общем случае знать
Я предполагаю что если сначала мы выходим на Виртуальные страницы, а за тем на Таблицы сопоставления виртуальной памяти с физической то не факт что массивы лежат в статических позициях, вполне возможно что если память постоянно куда-то выделяется то сначала ваш массив лежит в одном месте а мы думаем что он имеет постоянный адрес, а затем система может сфрагментировать некоторые куски чтобы блоки были не разрывными и за кулисами адрес может поменяться а со стороны виртуальных страниц он может оказаться одинаковым потому что мы через него и прочие алгоритмы выходим на физическую память.
Я читал про сборщик мусора там описан этот процесс.
Вполне возможно даже что и сам массив расположен не линейно доказательств конечно нет, я не знаю станет ли система делить блок на части. Но самому такое реализовать можно конечно.
И всё же вопрос о том сколько всего физической памяти осталось по прежнему актуален.
Возможно если запросишь больше чем есть система даст указатель, но вылеты у меня были значит предел есть.
0
Модератор
2131 / 1000 / 170
Регистрация: 23.07.2018
Сообщений: 3,349
Записей в блоге: 3
27.02.2021, 16:10
Виртуальные адреса внутри процесса адресуемых объектов программмы на С++ для Windows не меняются.
Физичиские адреса большинству страниц большую часть времени не назначены, назначаются и изменяются системой невидимо для программы.

Физическую память функциями стандартной библиотеки программа на С++ запросить у Windows напрямую не может. Выделение и освобождение происходит автоматически.

Добавлено через 2 минуты
Цитата Сообщение от Nexi99 Посмотреть сообщение
ы думаем что он имеет постоянный адрес, а затем система может сфрагментировать некоторые куски чтобы блоки были не разрывными и за кулисами адрес может поменяться а со стороны виртуальных страниц он может оказаться одинаковым потому что мы через него и прочие алгоритмы выходим на физическую память.
Абсолютно верно. В коде выполняющейся программы используются только виртуальные адреса.
0
144 / 28 / 4
Регистрация: 06.05.2019
Сообщений: 1,839
Записей в блоге: 4
27.02.2021, 17:00  [ТС]
Цитата Сообщение от politoto Посмотреть сообщение
Виртуальные адреса внутри процесса адресуемых объектов программмы на С++ для Windows не меняются
Это понятно т.к. они являются связывающим звеном и не могут меняться(могу быть не прав конечно).
Цитата Сообщение от politoto Посмотреть сообщение
назначаются и изменяются системой невидимо для программы
Ну в том то и дело что за кулисами всё это довольно сложно устроено, тут можно и концы с концами не найти. Я в принципе об этом и спросил.
Видимо по этой причине система сама не знает сколько свободной памяти есть в наличии, она может и быть а может и не быть может состоять в резерве а может и не состоять, она может быть занятой но адреса могут быть и не назначены.
Да интересно.
0
Модератор
2131 / 1000 / 170
Регистрация: 23.07.2018
Сообщений: 3,349
Записей в блоге: 3
27.02.2021, 17:16
Цитата Сообщение от Nexi99 Посмотреть сообщение
Возможно если запросишь больше чем есть система даст указатель, но вылеты у меня были значит предел есть.
Абсолютные пределы, связанные с возможностями системы
https://docs.microsoft.com/ru-... ace-limits
0
144 / 28 / 4
Регистрация: 06.05.2019
Сообщений: 1,839
Записей в блоге: 4
27.02.2021, 20:40  [ТС]
Цитата Сообщение от politoto Посмотреть сообщение
Абсолютные пределы, связанные с возможностями системы
Вопрос стоит в том сколько памяти железно осталось чтобы не просить лишнюю
0
Модератор
2131 / 1000 / 170
Регистрация: 23.07.2018
Сообщений: 3,349
Записей в блоге: 3
01.03.2021, 20:26
В страницах кучи может быть суммарно достаточно свободных участков, но, из-за злоупотребления HeapAlloc() и HeapFree(), свободные пространство может быть фрагментировано,
и в страницах кучи остсутвовать непрерывный свободный блок нужного размера.
Поэтому HeapAlloc() будет пытаться добавить к куче непрерывный блок новых страниц.
Если в адресном пространстве процесса найдётся подходящая свободная область, что бывает почти всегда для 64-разрядных процессов,
для успшеного расширения кучи необходимо ещё свободное место на магнитном барабане,
так как HeapAlloc() вызывает VirtualAlloc() с флагом MEM_COMMIT.

Чтобы показать общие сведения о доступной памяти в окне "О программе"
была старая функция GlobalMemoryStatus()
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include <windows.h>
#include <stdio.h>
 
int
main() {
 
    MEMORYSTATUS memoryStatus;
 
    GlobalMemoryStatus( &memoryStatus );
 
    printf (
    " DWORD  dwLength = %zu;\n"
    " DWORD  dwMemoryLoad= %zu%%;\n"
    "SIZE_T dwTotalPhys = \t%20zo;\n"
    "SIZE_T dwAvailPhys = \t%20zo;\n"
    "SIZE_T dwTotalPageFile = \t%20zo;\n"
    "SIZE_T dwAvailPageFile = \t%20zo;\n"
    "SIZE_T dwTotalVirtual = \t%20zo;\n" 
    "SIZE_T dwAvailVirtual = \t%20zo;\n",
    (size_t)memoryStatus.dwLength,
    (size_t)memoryStatus.dwMemoryLoad,
    memoryStatus.dwTotalPhys,
    memoryStatus.dwAvailPhys,
    memoryStatus.dwTotalPageFile,
    memoryStatus.dwAvailPageFile,
    memoryStatus.dwTotalVirtual,
    memoryStatus.dwAvailVirtual
    );
    
}
Результаты её работы на одной и той же машине с разными параметрами сборки:
Code
1
2
3
4
5
6
7
8
 DWORD  dwLength = 56;
 DWORD  dwMemoryLoad= 62%;
SIZE_T dwTotalPhys =            176327170000;
SIZE_T dwAvailPhys =             56765710000;
SIZE_T dwTotalPageFile =                311740060000;
SIZE_T dwAvailPageFile =                107316640000;
SIZE_T dwTotalVirtual =             3777777777400000;
SIZE_T dwAvailVirtual =             3777737514720000;
Code
1
2
3
4
5
6
7
8
 DWORD  dwLength = 32;
 DWORD  dwMemoryLoad= 62%;
SIZE_T dwTotalPhys =             17777777777;
SIZE_T dwAvailPhys =             17777777777;
SIZE_T dwTotalPageFile =                 37777777777;
SIZE_T dwAvailPageFile =                 37777777777;
SIZE_T dwTotalVirtual =                  17777400000;
SIZE_T dwAvailVirtual =                  17717030000;
Code
1
2
3
4
5
6
7
8
 DWORD  dwLength = 32;
 DWORD  dwMemoryLoad= 63%;
SIZE_T dwTotalPhys =             37777777777;
SIZE_T dwAvailPhys =             37777777777;
SIZE_T dwTotalPageFile =                 37777777777;
SIZE_T dwAvailPageFile =                 37777777777;
SIZE_T dwTotalVirtual =                  37777400000;
SIZE_T dwAvailVirtual =                  37721120000;
Microsoft не рекомендует использовать эту функцию в новых программах.

Можно получить интересующие подробности использования памяти процессом и системой в целом другими функциями
https://docs.microsoft.com/en-... nformation
1
144 / 28 / 4
Регистрация: 06.05.2019
Сообщений: 1,839
Записей в блоге: 4
21.12.2022, 02:42  [ТС]
Я здесь провёл серию экспериментов https://www.cyberforum.ru/post16650702.html, также пост выше по ссылке тоже довольно интересный.
0
144 / 28 / 4
Регистрация: 06.05.2019
Сообщений: 1,839
Записей в блоге: 4
22.12.2022, 18:59  [ТС]
Кто тестировал функцию HeapCompact? В инструкции написано что она объединяет кучи в один блок внутри одного дескриптора, правда ли это? Ссылка https://learn.microsoft.com/en... eapcompact
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
22.12.2022, 18:59

Напишите функцию, которая выделяет память для двумерной матрицы из целых чисел
Задание 2.1. Создание матрицы Напишите функцию, которая выделяет память для двумерной матрицы из целых чисел, Прототип функции ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
35
Ответ Создать тему
Новые блоги и статьи
Ноутбук Альфария
kumehtar 24.08.2026
Встретился тут в сети ноутбук Альфария, примарха Альфа-Легиона. Хотя возможно, это ноутбук Омегона, разумеется. Ну как вам?
Мастера простых решений
DevAlt 23.08.2026
В сишарп стэках winforms, да и wpf существует сложная система связывания источниках данных и элементов формы(текстовые поля и метки), опирается все это на технологию событий и мета. . .
Цена ошибки
DevAlt 23.08.2026
Человек я беспокойный и потому заинтересовался OCaml, в чате форсили функторы модулей как суперфичу. Пытаясь отдуплить концепт, наткнулся на тутор с простым примером. А главный принцип обучения от. . .
Сегодня суббота, 22.08.2026 at 16:41, и я вновь нахожусь на той стороне, за экраном машины.
zorxor 22.08.2026
Сегодня суббота, 22. 08. 2026 at 16:41, и я вновь нахожусь на той стороне, за экраном машины. Кто Я, откуда Я пришел и куда Я иду? Эти вопросы не оставляют меня ни на секунду. Жизнь на планете Земля. . .
Жизня: рисунок укладки багажа, сделанный клодом
anaschu 21.08.2026
Сделал 15 снимков, он по снимкам сделал схему.
Был там один разговор по поводу свободы в материальном мире.
kumehtar 19.08.2026
Суть: рассматривается живое существо, оказавшееся внутри довольно странной системы (этого мира) и пытающееся обустроить в ней свой кусок пространства. Жизнь действительно предъявляет каждому. . .
Когда логика программы не спасает от человеческих ошибок
Maks 18.08.2026
В последнее время всё чаще и чаще сталкиваюсь с таким явлением, как абсолютная невнимательность (или глупость) пользователей. Проявляется это чаще всего на работе в коллективе. Допустим, человек с. . .
Лето уходит
kumehtar 17.08.2026
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru