Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.92/37: Рейтинг темы: голосов - 37, средняя оценка - 4.92
 Аватар для Ivan Fantom
5 / 5 / 2
Регистрация: 12.10.2011
Сообщений: 75

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

11.07.2013, 22:45. Показов 7332. Ответов 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 ячейке массива вижла сообщает об ошибке.
Изначально я понимал, что выделить такой большой кусок памяти тривиальными средствами не получится. Но я просто не знаю какими средствами можно решить поставленную задачу.
Миниатюры
Выделите-ка под массив память размером 32 ГБ  
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
11.07.2013, 22:45
Ответы с готовыми решениями:

Используя указатели, выделите память для действительной переменной, заполните ее случайным числом
Используя указатели, выделите память для действительной переменной, заполните ее случайным числом, выведите результат на экран, не...

Не выделяется память под массив
void FloodFill_3(HDC hdc, RECT rect, COLORREF color, COLORREF border) //Растровая развертка многоугольников { //flags - состояние...

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

40
 Аватар для Kastaneda
5232 / 3205 / 362
Регистрация: 12.12.2009
Сообщений: 8,143
Записей в блоге: 2
12.07.2013, 11:24
Студворк — интернет-сервис помощи студентам
Где-то на форуме уже писал про это - на 64 битной ОС добиться std::bad_alloc еще постараться надо. Дело в том, что оператор new() работает с виртуальными адресами, и ничего не мешает выделить, например, 1 ТБ (это под Linux, в винде есть ограничение памяти на процесс, вроде 17 гигов, но точно не помню). Если выделить 10 ТБ, то никакого std::bad_alloc не будет, все пройдет хорошо. Проблемы начнутся при записи/чтении в/из этой памяти. Потому обертывать new в try{}catch(){} на 64 битной ОС по сути бесполезное занятие.
1
5499 / 4894 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
12.07.2013, 14:45
Цитата Сообщение от Kastaneda Посмотреть сообщение
Где-то на форуме уже писал про это - на 64 битной ОС добиться std::bad_alloc еще постараться надо. Дело в том, что оператор new() работает с виртуальными адресами, и ничего не мешает выделить, например, 1 ТБ (это под Linux, в винде есть ограничение памяти на процесс, вроде 17 гигов, но точно не помню). Если выделить 10 ТБ, то никакого std::bad_alloc не будет, все пройдет хорошо. Проблемы начнутся при записи/чтении в/из этой памяти. Потому обертывать new в try{}catch(){} на 64 битной ОС по сути бесполезное занятие.
Вот код и результат на 64-битной XP:
C++
1
2
3
4
5
6
7
8
9
int main()
{
    unsigned long long size = 1024*1024*1024;
    size *= 32;
 
    char* ms = new char[size];
    
    return 0;
}
Миниатюры
Выделите-ка под массив память размером 32 ГБ  
0
 Аватар для Programmer c
5 / 0 / 0
Регистрация: 06.07.2013
Сообщений: 59
12.07.2013, 15:05
Многовато))) 32 гб)
0
 Аватар для Kastaneda
5232 / 3205 / 362
Регистрация: 12.12.2009
Сообщений: 8,143
Записей в блоге: 2
12.07.2013, 15:09
alsav22, я ж написал, что в винде ограничение на каждый процесс есть. Вот на 64 битном Linux'е запустил такой код
C++
1
2
3
4
5
6
7
8
9
10
11
12
#include <iostream>
 
int main() 
{
    for (int i = 0; i < 1024 * 100; i++) { // всего "выделится" 100 ТЕРАбайт
        try {
            char *p = new char[1024 * 1024 * 1024];
        } catch (std::exception &e) {
            std::cout << e.what() << std::endl;
        }
    }
}
код отработал молча, т.е. память как бы выделилась.
0
12.07.2013, 17:42

Не по теме:

Цитата Сообщение от Kastaneda Посмотреть сообщение
alsav22, я ж написал, что в винде ограничение на каждый процесс есть.
Прошу прощения, пропустил, что это про Linux пишется.

0
 Аватар для Kastaneda
5232 / 3205 / 362
Регистрация: 12.12.2009
Сообщений: 8,143
Записей в блоге: 2
12.07.2013, 17:53
Цитата Сообщение от alsav22 Посмотреть сообщение
пропустил, что это про Linux пишется.
Не то, чтобы совсем под Linux, т.к. Windows это тоже касается. Даже несмотря на виндовые ограничения в x86_64 все равно можно "выделить" больше памяти, чем есть реально (ну только если физически все же меньше памяти, чем ограничение в N гигов).
У меня нет 64 битной винды, проверить доступный размер не могу, но, если кому не сложно, можно выполнить следующий код и выложить результат.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <iostream>
 
int main() 
{
    for (int i = 0; i < 1024 * 100; i++) { 
        try {
            char *p = new char[1024 * 1024 * 1024];
            std::cout << i << "GB" << std::endl;
        } catch (std::exception &e) {
            std::cout << e.what() << std::endl;
            return 0;
        }
    }
}
если исключение выкинется сразу, то можно поступить так
C++
1
char *p = new char[1024 * 1024 * 1024 / 2];
0
5499 / 4894 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
12.07.2013, 18:03
Это при 4Гб памяти.
Миниатюры
Выделите-ка под массив память размером 32 ГБ  
0
 Аватар для Kastaneda
5232 / 3205 / 362
Регистрация: 12.12.2009
Сообщений: 8,143
Записей в блоге: 2
12.07.2013, 18:09
Хм, странно, я своими глазами видел, как винда выдавала сообщение про ограничение в 17 (точно не помню) GB. Может в винде такие вещи где-то настраиваются.
0
5499 / 4894 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
12.07.2013, 18:28
Но не болше же чем физической памяти?
0
В астрале
Эксперт С++
 Аватар для ForEveR
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
12.07.2013, 19:22
Kastaneda, Данный код подвесил мою систему наглухо... bad_alloc не дождался... Вообщем, жесть)
В release после 3 ГБ вышел bad_alloc, 4 ГБ в системе.
http://stackoverflow.com/quest... -a-program
On 32-bit Windows your application would stop at 4GB. On 64-bit Windows your application will stop at 16TB (assuming you have a page file that can grow automatically, and that much hard disk space).
0
 Аватар для Kastaneda
5232 / 3205 / 362
Регистрация: 12.12.2009
Сообщений: 8,143
Записей в блоге: 2
12.07.2013, 19:35
Цитата Сообщение от ForEveR Посмотреть сообщение
Данный код подвесил мою систему наглухо..
Интересно получается. Под линуксом этот код выполняется довольно быстро и на систему ни как не влияет (хотя я за памятью не следил во время выполнения). А под виндой похоже память реально пытается выделиться (раз система виснет) и, когда ОЗУ заканчивается, то место ищется на харде (хотя я не совсем понимаю как работает винда). В линуксе же размер swap'a тоже ограничен, а в винде походу нет.

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

Добавлено через 2 минуты
Цитата Сообщение от ForEveR Посмотреть сообщение
Данный код подвесил мою систему наглухо... bad_alloc не дождался...
а, кстати, сколько гигов оно успело выделить прежде чем повиснуть?
0
В астрале
Эксперт С++
 Аватар для ForEveR
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
12.07.2013, 19:38
Kastaneda, 1 или 2. Но это был дебаг. В релизе все крайне быстро
0
12.07.2013, 19:42

Не по теме:

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

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

//Если я в чем-то не прав, разьясните пожалуйста в чем..
0
Эксперт С++
 Аватар для Thinker
4267 / 2241 / 203
Регистрация: 26.08.2011
Сообщений: 3,802
Записей в блоге: 5
12.07.2013, 20:07
Цитата Сообщение от Bend3r Посмотреть сообщение
К сожалению, я не знаю сколько памяти занимает тип int (2 по-моему).
все зависит от версии компилятора и марки компьютера. и 2 байта, и 4 бывают.
0
 Аватар для Kuzia domovenok
4268 / 3327 / 926
Регистрация: 25.03.2012
Сообщений: 12,531
Записей в блоге: 1
12.07.2013, 21: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
12.07.2013, 21:39

Не по теме:

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

0
13.07.2013, 02:41

Не по теме:

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

0
 Аватар для Ivan Fantom
5 / 5 / 2
Регистрация: 12.10.2011
Сообщений: 75
13.07.2013, 03:18  [ТС]
Ребята, вы ушли в сторону от задачи.
Итак 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
Ушел с форума
Эксперт С++
 Аватар для Убежденный
16481 / 7444 / 1187
Регистрация: 02.05.2013
Сообщений: 11,616
Записей в блоге: 1
13.07.2013, 10:06
Цитата Сообщение от 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
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
13.07.2013, 10:06
Помогаю со студенческими работами здесь

Выделить память под двумерный массив
Есть програмка, нужно сделать что-бы массив mass был двумерный размером 7х4. Malloc должен работать. #include &lt;stdio.h&gt; /*malloc*/ ...

Где выделяется память под массив
Здравствуйте! Данный код является валидным и компилируется в gcc 5.3.1 без ошибок. По данному коду есть несколько вопросов. ...

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

Дан двумерный массив на 5х5 размером. Заполнить нулями под главной диагональю
#include&lt;stdio.h&gt; #include&lt;conio.h&gt; int main() { int ar,i,j; for(i=0;i&lt;5;i++) { for(j=0;j&lt;5;j++) { printf(&quot;ar:...

Почему не выделяется память под двумерный массив?
**ptrarray = new float* ; for (int i = 0; i &lt; h; i++){ ptrarray = new float ; } Пишет: Вызвано исключение:...


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

Или воспользуйтесь поиском по форуму:
40
Ответ Создать тему
Новые блоги и статьи
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru