Форум программистов, компьютерный форум, киберфорум
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 19, средняя оценка - 4.79
Ivan Fantom
5 / 5 / 1
Регистрация: 12.10.2011
Сообщений: 75
#1

Выделите-ка под массив память размером 32 ГБ - C++

11.07.2013, 22:45. Просмотров 2710. Ответов 40
Метки нет (Все метки)

Получил ряд вопросов от одной фирмы. Надо ответить чтобы удостоить себя собесодованием) Вот один из них.

Словесно представьте вашу последовательность действий при написании программного кода заданий описанных ниже с учетом всех возможных на Ваш взгляд багов:

а) Приведите любой пример выделения памяти под массив, где размер выделяемой памяти должен составлять = 235 байт и заполните его случайными значениями.

б) Переэлокейтите массив, чтобы его размерность увеличилась с 235 до 235 + 100.

Про а)
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
int main()
{
    unsigned long long size = 1024*1024*1024;
    size *= 32;
 
    char* ms = new char[size];
    
    for(int i=0;i<size;i++)
        ms[i] = i + '0';
 
    cout << ms[size-1] << endl;
 
    delete[] ms;
    return 0;
}
Само выделение памяти прошло без проблем, а вот когда началась инициализация, то на 1305 ячейке массива вижла сообщает об ошибке.
Изначально я понимал, что выделить такой большой кусок памяти тривиальными средствами не получится. Но я просто не знаю какими средствами можно решить поставленную задачу.
0
Миниатюры
Выделите-ка под массив память размером 32 ГБ  
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
11.07.2013, 22:45
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Выделите-ка под массив память размером 32 ГБ (C++):

Динамически выделить память под массив - C++
Задание было в следующем: дан вещественный двумерный массив А. Поменять местами максимальный элемент главной и побочной диагоналей с...

Динамически выделить память под массив - C++
Добрый день форусчани Как можно выделить память под массив объекта класса class Save_Colection { public: pk *field; ...

Выделить и удалить память под 4 мерный массив - C++
пацаны помогите.. Добавлено через 1 час 11 минут .помогите..не могу вобще натйи 4 мерные масивы..только 2хмерные

Как выделяется память под массив string? - C++
В общем читаю книжку, там объявлены два массива int* p = new int, int* v = new string... бла бла бла ....а потом -&gt; ...После резервирования...

Выделить память под динамический массив указателей - C++
Нужно выделить память вот под такое дело. Для примера n=5 . Ничего нагуглить так и не смог :( что есть : #include &quot;stdafx.h&quot; ...

Как выделить память под массив в структуре? - C++
Здравствуйте , воnрос конечно глуnый , но голову я сижу ломаю долго , есть Структура , в ней есть массив , как nод этот массив выделить...

40
Kastaneda
Jesus loves me
Эксперт С++
4697 / 2901 / 238
Регистрация: 12.12.2009
Сообщений: 7,385
Записей в блоге: 2
Завершенные тесты: 1
12.07.2013, 19:35 #31
Цитата Сообщение от ForEveR Посмотреть сообщение
Данный код подвесил мою систему наглухо..
Интересно получается. Под линуксом этот код выполняется довольно быстро и на систему ни как не влияет (хотя я за памятью не следил во время выполнения). А под виндой похоже память реально пытается выделиться (раз система виснет) и, когда ОЗУ заканчивается, то место ищется на харде (хотя я не совсем понимаю как работает винда). В линуксе же размер swap'a тоже ограничен, а в винде походу нет.

Добавлено через 3 минуты
Цитата Сообщение от Kastaneda Посмотреть сообщение
а в винде походу нет.
а не, гоню, ограничен. И его руками поменять можно.

Добавлено через 2 минуты
Цитата Сообщение от ForEveR Посмотреть сообщение
Данный код подвесил мою систему наглухо... bad_alloc не дождался...
а, кстати, сколько гигов оно успело выделить прежде чем повиснуть?
0
ForEveR
В астрале
Эксперт С++
7983 / 4742 / 321
Регистрация: 24.06.2010
Сообщений: 10,547
Завершенные тесты: 3
12.07.2013, 19:38 #32
Kastaneda, 1 или 2. Но это был дебаг. В релизе все крайне быстро
0
Kastaneda
12.07.2013, 19:42
  #33

Не по теме:

За что люблю линукс, так это за то, что когда что-то не понятно, можно взять и посмотреть в исходниках как оно реально работает. А когда в винде что-то непонятно, нужно искать ответ на msdn, если там не нашел, то гуглить, если не нагуглил, то спросить на форуме, если на форуме не помогут, то ответа на свой вопрос ты так и не узнаешь (если конечно нет желания погрузиться на несколько месяцев в дизассемблер).

0
Bend3r
149 / 136 / 18
Регистрация: 29.07.2012
Сообщений: 709
12.07.2013, 19:57 #34
Я пока еще не опытен в C++, но по-моему можно же сделать так.
К сожалению, я не знаю сколько памяти занимает тип int (2 по-моему).
Допустим вам надо выделить 256 кб, ну и примерно так int *a = new int[128];

//Если я в чем-то не прав, разьясните пожалуйста в чем..
0
Thinker
Эксперт С++
4228 / 2202 / 150
Регистрация: 26.08.2011
Сообщений: 3,802
Записей в блоге: 5
12.07.2013, 20:07 #35
Цитата Сообщение от Bend3r Посмотреть сообщение
К сожалению, я не знаю сколько памяти занимает тип int (2 по-моему).
все зависит от версии компилятора и марки компьютера. и 2 байта, и 4 бывают.
0
Kuzia domovenok
2030 / 1874 / 168
Регистрация: 25.03.2012
Сообщений: 6,451
Записей в блоге: 1
12.07.2013, 21:36 #36
Цитата Сообщение от Kastaneda Посмотреть сообщение
За что люблю линукс, так это за то, что когда что-то не понятно, можно взять и посмотреть в исходниках как оно реально работает. А когда в винде что-то непонятно, нужно искать ответ на msdn, если там не нашел, то гуглить, если не нагуглил, то спросить на форуме, если на форуме не помогут, то ответа на свой вопрос ты так и не узнаешь (если конечно нет желания погрузиться на несколько месяцев в дизассемблер).
по-моему, это наоборот одна из многочисленных причин ненавидеть Linux.
Цитата Сообщение от Bend3r Посмотреть сообщение
Я пока еще не опытен в C++, но по-моему можно же сделать так.
К сожалению, я не знаю сколько памяти занимает тип int (2 по-моему).
Допустим вам надо выделить 256 кб, ну и примерно так int *a = new int[128];
Если смотреть на достаток/нехватку памяти, то результат этих операций будет одинаков.
C++
1
2
int *a = new int[N];
char *b = new char[N*sizeof(int)];
0
Kastaneda
12.07.2013, 21:39
  #37

Не по теме:

Цитата Сообщение от Kuzia domovenok Посмотреть сообщение
по-моему, это наоборот одна из многочисленных причин ненавидеть Linux.
Kuzia domovenok, я промолчу потому что очень очень неохото разводить очередной холивар

0
alsav22
13.07.2013, 02:41
  #38

Не по теме:

Цитата Сообщение от Bend3r Посмотреть сообщение
//Если я в чем-то не прав, разьясните пожалуйста в чем..
В том, что не читаете предыдущих постов.

0
Ivan Fantom
5 / 5 / 1
Регистрация: 12.10.2011
Сообщений: 75
13.07.2013, 03:18  [ТС] #39
Ребята, вы ушли в сторону от задачи.
Итак malloc/new 32 ГБ никак не выделят. Вдобавок size_t просто урежет значение переменной размера.

Я пробовал использовать функции VirtualAlloc и VirtualFree, которые являются более гибкими средствами выделения памяти.

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
#include <malloc.h>
#include "windows.h"
#include <iostream>
using namespace std;
 
void main()
{
    size_t MEMSIZE = 6442450944ULL; //6GB
    char* p = (char*)VirtualAlloc(NULL,MEMSIZE,MEM_COMMIT,PAGE_READWRITE);
 
    if (p!=NULL)
        cout << "OK Alloc " << endl;
    else
    {
        cout << "Error Alloc " << endl;
        
        if (VirtualFree(p,0,MEM_RELEASE))
            cout << "Ok Free";
        else cout << "Not Free" << endl;
        return;
    }
    
    for(size_t i = 0;i<MEMSIZE;i++)
        *(p+i) = (int)i + '0';
 
    cout << p[MEMSIZE-1] << endl;
 
    if (VirtualFree(p,0,MEM_RELEASE))
        cout << "Ok Free";
    else cout << "Not Free" << endl;
}
И результат был таков.

Конфигурация проекта Win32. Память выделилась (с предупреждением об усечении значения переменной размера) размером в 4096, что вполне ожидаемо, ведь VirtualAlloc память выделяет блоками по 4096 байт, и соответственно указанный размер будет округляться до этого числа.

Конфигурация проекта x64. VirtualAlloc возвращает нулевой указатель, что говорит о неудачном выделении. Зато успешно выделялась и заполнялась случайными значениями память объемом 2 ГБ, 3 ГБ. При 5 ГБ вся моя оперативная память была занята и система зависла.

Есть еще такой механизм свопинга, заключающийся в том, что каждый процесс полностью переносится в память, работает некоторое время и потом целиком возвращается на диск. Другая стратегия – виртуальная память – позволяет программам работать даже тогда, когда они частично находятся в оперативной памяти.
Система использует механизм виртуализации адресов при необходимости, но почему-то на мое приложение механизм не распространяется, когда объем выделяемой памяти превышает объем свободной оперативной памяти.
0
Убежденный
Ушел с форума
Эксперт С++
15708 / 7218 / 1139
Регистрация: 02.05.2013
Сообщений: 11,637
Записей в блоге: 1
Завершенные тесты: 1
13.07.2013, 10:06 #40
Цитата Сообщение от Ivan Fantom Посмотреть сообщение
Ребята, вы ушли в сторону от задачи.
Как мне кажется, смысл данной задачи не в том, чтобы найти способ выделить 32 ГБ под
массив, а в том, чтобы предложить хорошую абстракцию для работы с таким массивом.
Например, можно написать что-то вроде класса large_array, который будет хранить свое
содержимое на диске, в 32-гигабайтном файле, и предоставлять клиентам доступ к нужным
элементам, загружая их в память по мере необходимости. На Windows наиболее естественным
для этого будет использовать отображаемые в память файлы. Сверху можно навесить кэш, в
котором хранить некоторое количество последних элементов, запрошенных клиентами, для
ускорения доступа (чтобы не дергать диск каждый раз). Но в любом случае это получится
"дырявая" абстракция: с таким массивом нельзя будет работать также, как с обычным -
доступ к памяти нужно будет делать косвенный, например, через дескрипторы, не будет
безопасным выполнять memset на диапазоне элементов такого массива, и т.п.

Цитата Сообщение от Ivan Fantom Посмотреть сообщение
Конфигурация проекта Win32. Память выделилась (с предупреждением об усечении значения переменной размера) размером в 4096, что вполне ожидаемо, ведь VirtualAlloc память выделяет блоками по 4096 байт, и соответственно указанный размер будет округляться до этого числа.
Задача о выделении 32-гигабайтного массива в 32-разрядном процессе нерешаема в принципе.
В каталоге страниц памяти 32-битного процесса просто нет столько места, чтобы хранить
описание массива в 32 гигабайта. Пользовательским процессам в 32-битном адресном
пространстве доступно чуть меньше 2 гигабайт, ключ /3GB принципиально картины не меняет.
О непрерывном блоке памяти такого размера в 32-битном процессе можно забыть.

Цитата Сообщение от Ivan Fantom Посмотреть сообщение
Конфигурация проекта x64. VirtualAlloc возвращает нулевой указатель, что говорит о неудачном выделении.
Не хватило файла подкачки, скорее всего (проверьте GetLastError == 1455).
Кстати, вместо увеличения файла подкачки можно выделить зарезервированный блок (MEM_RESERVE)
охраняемых страниц (PAGE_GUARD) и коммитить их только при попытках доступа, а старые страницы
при этом снова отправлять в резерв. То есть, получится такой аллокатор памяти с отслеживанием
нарушений доступа по исключению. Система использует этот механизм для динамического увеличения
размера стека.

Цитата Сообщение от Ivan Fantom Посмотреть сообщение
Система использует механизм виртуализации адресов при необходимости,
но почему-то на мое приложение механизм не распространяется, когда объем выделяемой памяти
превышает объем свободной оперативной памяти.
Распостраняется. Виртуальная память используется всегда, ее поддержка обеспечена аппаратно, в
том числе на уровне CPU. Но существует путаница между виртуальной памятью и файлом подкачки,
хотя это разные вещи.
2
Kastaneda
13.07.2013, 13:18     Выделите-ка под массив память размером 32 ГБ
  #41

Не по теме:

Цитата Сообщение от Убежденный Посмотреть сообщение
Виртуальная память используется всегда, ее поддержка обеспечена аппаратно, в
том числе на уровне CPU.
Лирическое дополнение - если CR0.PG = 1, т.е. если включен пэйджинг.

0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
13.07.2013, 13:18
Привет! Вот еще темы с ответами:

Динамически выделить память под массив функций - C++
QByteArray (SerfingThread::*lp_GetRequest)(const QByteArray&amp; ,const QByteArray&amp;); как сделать тоже самое только через new? как правильно...

Выделить память под массив неизвестной длины - C++
для программы нужен массив int Array т.е. длину строки я знаю, а сколько строк у меня будет - не представляю. я знаю, что...

Выделить память под массив размера 2^64 байтов - C++
Требуется выделить память под массив размера 2^64 байтов. Как порекомендуете решать данную задачу?

Почему не очищает память, выделенную под массив структур - C++
#include &lt;cstdlib&gt; #include &lt;iostream&gt; using namespace std; const int ar_size=20; struct CandyBar { char name; double...


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

Или воспользуйтесь поиском по форуму:
41
13.07.2013, 13:18
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.