Форум программистов, компьютерный форум CyberForum.ru

Нужно выделить всю доступную процессу память блоками по 13 байт - C++

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 12, средняя оценка - 4.83
nexen
187 / 180 / 3
Регистрация: 27.01.2012
Сообщений: 1,335
03.10.2012, 10:51     Нужно выделить всю доступную процессу память блоками по 13 байт #1
Нужно выделить всю доступную процессу память блоками по 13 байт.
Использовать нужно две функции :
malloc
HeapAlloc
При этом нужно потом посчитать количество памяти (не при выделении) и освободить её.

Как это вообще сделать? Завести вектор, где каждый элемент будет хранить указатель на 13 байт, а затем выделять каждому новому элементу блок памяти, пока malloc/HeapAlloc не закричит об ошибке? Но тогда есть шанс, что у процесса не использовано 0-12 байт памяти. Как поступать в этом случае? При ошибке пройтись от 12 до 1 и выделять последовательно на "добив"?
Более того, является ли "максимально доступная процессу память" статическим числом? Т.е, есть ли шанс, что, когда я выделил память по 13 блоков и в конце остался блок 5 байт, я начинаю идти по циклу 12->1 на "добив", но в этот момент *ХОП* и у процесса можно выделить ещё 15мб?..

Всё, что есть у меня :
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
31
32
33
34
35
36
37
38
39
40
#include <windows.h>
#include <stdio.h>
#include <conio.h>
#include <vector>
using std::vector;
 
#define MEM_BLOCK 13
 
int main() 
{
    HANDLE heap = HeapCreate(0, 0, 0); // GetProcessHeap(); не знаю, что из двух использовать
    char *var = (char*)HeapAlloc(heap, HEAP_ZERO_MEMORY, MEM_BLOCK);
    vector <char*> memory;
    while (var != NULL)
    {
        memory.push_back(var);
        var = (char*)HeapAlloc(heap, HEAP_ZERO_MEMORY, MEM_BLOCK);
    }
 
    int lastMemCapacity;
    char *lastMem;
    for (int i = MEM_BLOCK-1; i>=1; ++i)
    {
        lastMem = (char*)HeapAlloc(heap, HEAP_ZERO_MEMORY, MEM_BLOCK);
        if (lastMem != NULL)
        {
            lastMemCapacity = i;
            break;
        }
    }
 
    printf("Size : %I64d\n", __int64(memory.size())*MEM_BLOCK+lastMemCapacity);
 
    /*for (unsigned int i=0; i<memory.size(); ++i)
        free(memory[i]);
    free(lastMem); // For Malloc */
 
    _getch();
    return 0;
}
Но в данном случае выкидывает исключение ещё при первом выделении памяти - что странно, ведь (как написано на msdn.. либо как я понял) heapalloc должна давать NULL, если не хватает памяти, а не выбрасывать exception. Я ведь не давал на то согласие в параметрах.

p.s Или можно забить на vector, выделяя память в указатель var каждый новый раз и забывая указатель на предыдущий блок? В конце просто дать heapsize и heapfree? Не будет потерь? Более того, heapsize требует указатель на начало выделенной памяти. А у меня этих указателей over 9000 :<

Добавлено через 11 минут
Проверочка вида :
C++
1
2
3
4
5
6
7
8
try
{
    var = (char*)HeapAlloc(heap, HEAP_ZERO_MEMORY, MEM_BLOCK);
}
catch (...)
{
    break;
}
Почему-то не катит :<
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
03.10.2012, 10:51     Нужно выделить всю доступную процессу память блоками по 13 байт
Посмотрите здесь:

Нужно выделить память в куче C++
Для целого числа А выделить старший байт и поставить его на место младшего байта. старший байт при этом обнулить. C++
C++ Работа с вводом. Нужно в зависимости от кол. введенных чисел выделить память
Как выделить память? C++
OpenCV сжирает всю память и система зависает C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
DU
1477 / 1053 / 45
Регистрация: 05.12.2011
Сообщений: 2,279
03.10.2012, 10:53     Нужно выделить всю доступную процессу память блоками по 13 байт #2
можно организовать что-то вроде связного списка. выделили блок. запомнили указатель на блок.
выделили следующий. сохранили указатель на этот новый блок в предыдущем и так далее. указатели не потеряются.
И еще чтобы по началу упростить себе жизнь, лучше работать не напрямую с функциями выделения памяти, а написать какой-нибудь классик, в котором можно задавать количество памяти и выделять эту память через такой класс. он будет вести статистику и когда память типа закончится, функции выделения памяти этого класса начнут возвращать нули или еще что-то. при этом реальную память даже не обазательно выделять. так вот можно будет смоделировать основные алгоритмы. после этого имплемент функций этого класса сделать таким, чтобы уже реально в процессе выделялась память.
nexen
187 / 180 / 3
Регистрация: 27.01.2012
Сообщений: 1,335
03.10.2012, 19:10  [ТС]     Нужно выделить всю доступную процессу память блоками по 13 байт #3
DU, к сожалению, задача именно в прямом (не через классы или ещё чего) выделении памяти malloc'ом и heap'ом. Если malloc при недостаточной памяти возвращает NULL, то heap выбрасывает exception, который я не могу перехватить почему-то. Ставил и catch(...) и catch(std::bad_alloc&) - ничего..
Более того мне всё же не ясно, будет ли max-память процесса статической или она может измениться во время выделения?

Добавлено через 25 минут
Финальный код имеет вид :
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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
#include <windows.h>
#include <stdio.h>
#include <conio.h>
#include <vector>
#include <exception>
using namespace std;
 
#define MEM_BLOCK 17048
 
int main() 
{
    vector <char*> blocks;
    long long timeStart = GetTickCount64(), timeAllocation, timeRelease;
    char *newBlock = (char*)malloc(MEM_BLOCK);
    while (newBlock != NULL)
    {
        blocks.push_back(newBlock);
        newBlock = (char*)malloc(MEM_BLOCK);
    }
    
    char *lastBlock = NULL;
    int memoryUsage, lastBlockSize;
    for (int i = MEM_BLOCK-1; i>=0 && !lastBlock; --i)
    {
        lastBlock = (char*)malloc(i);
        lastBlockSize = i;
    }
    timeAllocation = (GetTickCount64()-timeStart)/1000;
    memoryUsage = blocks.size()*MEM_BLOCK+lastBlockSize;
    timeStart = GetTickCount64();
    for (unsigned int i=0; i<blocks.size(); ++i)
        free(blocks[i]);
    free(lastBlock);
    timeRelease = (GetTickCount64()-timeStart)/1000;
 
    printf("Method : Malloc\n");
    printf("Allocation time : %ld sec\n", timeAllocation);
    printf("Size : %ld bytes\n", memoryUsage);
    printf("Release time : %ld sec\n\n", timeRelease);
    blocks.clear();
    newBlock = lastBlock = NULL;
    
 
    HANDLE heap = HeapCreate(0, 0, 0); // Holy shit! It is 0x0000000-heap. Explode the brain, please
    //DWORD x = GetLastError(); // 8 - not enough memory
timeStart = GetTickCount64();
    newBlock = (char*)HeapAlloc(heap, HEAP_ZERO_MEMORY, MEM_BLOCK); // error with 0-heap
    while (newBlock != NULL)
    {
        blocks.push_back(newBlock);
        newBlock = (char*)HeapAlloc(heap, HEAP_ZERO_MEMORY, MEM_BLOCK);
    }
 
    for (int i = MEM_BLOCK-1; i>=0 && !lastBlock; --i)
    {
        lastBlock = (char*)HeapAlloc(heap, HEAP_ZERO_MEMORY, MEM_BLOCK);
        lastBlockSize = i;
    }
    timeAllocation = (GetTickCount64()-timeStart)/1000;
    memoryUsage = blocks.size()*MEM_BLOCK+lastBlockSize;
    timeStart = GetTickCount64();
    for (unsigned int i=0; i<blocks.size(); ++i)
        HeapFree(heap, 0, blocks[i]);
    HeapFree(heap, 0, lastBlock);
    timeRelease = (GetTickCount64()-timeStart)/1000;
 
    printf("Method : HeapAlloc\n");
    printf("Allocation time : %ld sec\n", timeAllocation);
    printf("Size : %ld bytes\n", memoryUsage);
    printf("Release time : %ld sec\n\n", timeRelease);
    blocks.clear();
    newBlock = lastBlock = NULL;
 
    _getch();
    return 0;
}
Ошибка там, где комментарий. Дело в том, что HeapCreate возвращает ошибку №8 - недостаточно памяти для команды. Но почему? Я ведь сделал free для всех блоков. Да даже если и не для всех, то хотя бы 1 кб свободный да остался бы после free. (Диспетчер показывает, что память занимает только сам MS visual studio, а значит хоть что-то да освободилось)

Добавлено через 1 час 59 минут
Идей совсем нет? ; (

Добавлено через 55 минут
И ещё. Такой подход не выделяет абсолютно всю память, которая есть физически. Остается порядка 10% (400 мб), а выделенная память всегда равна примерно ~2.2гб

Добавлено через 4 часа 12 минут
up-to-date
Если я плохо выразил вопрос, и он не понятен, то напишите, я попробую переформулировать или ещё чего ; (
Nick Alte
Эксперт С++
1561 / 982 / 115
Регистрация: 27.09.2009
Сообщений: 1,896
Завершенные тесты: 1
03.10.2012, 19:34     Нужно выделить всю доступную процессу память блоками по 13 байт #4
В 32-битной Windows (или в 64-битной, но 32-битным приложениям) процессу доступно 2 гигабайта линейного адресного пространства (2^31 байтов). В это пространство укладывается некоторая служебная информация, образ исполняемого файла и используемых им DLL, остальное доступно для "захвата". Этому линейному пространству (разумеется, если соответствующий кусок запрошен у ОС) ставятся в соответствие в произвольном порядке страницы физической памяти. Если физической памяти меньше, то незаметно для приложения используется файл подкачки. В принципе, он может использоваться даже если физической памяти хватает, но ОС считает, что какие-то страницы можно скинуть в дальний ящик. Если памяти больше, то процесс до неё уже так просто не дотянется.
64-битные приложения могут адресовать намного больше памяти. Так что ничто не мешает съесть всю физическую и забить своп-файлом всё свободное место на винчестере.
nexen
187 / 180 / 3
Регистрация: 27.01.2012
Сообщений: 1,335
04.10.2012, 20:12  [ТС]     Нужно выделить всю доступную процессу память блоками по 13 байт #5
Nick Alte, спасибо, теперь чуть более понятно. Однако встает другой вопрос - почему при каждом новом запуске выделяется разное кол-во памяти? Ведь тогда оно было бы всегда 2^31?

p.s Ну и всё ещё проблема с HeapCreate после malloc/free

Добавлено через 16 часов 42 минуты
up-to-date ; (

Добавлено через 7 часов 43 минуты
up-to-date?
ProNoooob
71 / 71 / 6
Регистрация: 14.10.2009
Сообщений: 121
04.10.2012, 20:39     Нужно выделить всю доступную процессу память блоками по 13 байт #6
Цитата Сообщение от nexen Посмотреть сообщение
p.s Ну и всё ещё проблема с HeapCreate после malloc/free
То есть вы после освобождения памяти функцией free() пытаетесь опять выделить ее функциями ОС?
В таком случае полезно знать, что функция free() не возвращает память операционной системе ^_^
А как-бы оставляет на будущее для вашей программы. Чтобы быстрее выделять новые блоки.

А по функциям WinAPI совет один. Читать английский msdn.
Там все подробно описано.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
05.10.2012, 12:35     Нужно выделить всю доступную процессу память блоками по 13 байт
Еще ссылки по теме:

C++ Cчитывание из файла блоками по 8 байт
Отображение файла в память, поиск и замена последовательности байт C++
C++ Динамическая память - блоками

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

Или воспользуйтесь поиском по форуму:
nexen
187 / 180 / 3
Регистрация: 27.01.2012
Сообщений: 1,335
05.10.2012, 12:35  [ТС]     Нужно выделить всю доступную процессу память блоками по 13 байт #7
Проблема решена. Спасибо ProNoooob.
Дело было в том, что, после освобождения памяти free/HeapFree, нужно так же разрушать кучу при помощи HeapDestroy.
Yandex
Объявления
05.10.2012, 12:35     Нужно выделить всю доступную процессу память блоками по 13 байт
Ответ Создать тему
Опции темы

Текущее время: 12:37. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru