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

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

Восстановить пароль Регистрация
 
 
Рейтинг: Рейтинг темы: голосов - 19, средняя оценка - 4.79
Ivan Fantom
 Аватар для Ivan Fantom
5 / 5 / 1
Регистрация: 12.10.2011
Сообщений: 75
11.07.2013, 22:45     Выделите-ка под массив память размером 32 ГБ #1
Получил ряд вопросов от одной фирмы. Надо ответить чтобы удостоить себя собесодованием) Вот один из них.

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

а) Приведите любой пример выделения памяти под массив, где размер выделяемой памяти должен составлять = 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 ГБ  
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
coloc
погромист
 Аватар для coloc
409 / 245 / 15
Регистрация: 27.08.2012
Сообщений: 550
Завершенные тесты: 1
11.07.2013, 22:48     Выделите-ка под массив память размером 32 ГБ #2
через вектор попробуйте
Kuzia domovenok
 Аватар для Kuzia domovenok
1882 / 1737 / 116
Регистрация: 25.03.2012
Сообщений: 5,907
Записей в блоге: 1
11.07.2013, 22:53     Выделите-ка под массив память размером 32 ГБ #3
чего-то я не вижу связи между вопросом и кодом. Плохо гляжу?
Вопрос про "размер выделяемой памяти должен составлять = 235 байт"
Код про "size = 32*1024*1024*1024;"
Так вопрос про 235 байт или 32 Гб?
Ivan Fantom
 Аватар для Ivan Fantom
5 / 5 / 1
Регистрация: 12.10.2011
Сообщений: 75
11.07.2013, 23:00  [ТС]     Выделите-ка под массив память размером 32 ГБ #4
виноват, там 235 байта т.е. 32 Гб
karaulov6
15 / 15 / 1
Регистрация: 23.03.2013
Сообщений: 140
11.07.2013, 23:25     Выделите-ка под массив память размером 32 ГБ #5
может там ошиблись и нужно 32 метра? ну могу только удачи пожелать с 32 ГБ
DU
1477 / 1053 / 45
Регистрация: 05.12.2011
Сообщений: 2,279
11.07.2013, 23:27     Выделите-ка под массив память размером 32 ГБ #6
странно что вы не словили исключение. или у вас есть 32 гигабайта?
может быть это из-за срезки. сигнатура оператора new [] такая:
void* operator new (std::size_t size) throw (std::bad_alloc);
если у вас 32 битка и не было срезки в unsigned long long, то будет при касте unsigned long long в std::size_t.
вопрос наверняка хитрый и такое решение в лоб - это врятли. что там могут быть за грабли - я даже не знаю.
если узнаете, расскажите плиз.
IsRiot
 Аватар для IsRiot
9 / 9 / 2
Регистрация: 05.07.2013
Сообщений: 86
11.07.2013, 23:29     Выделите-ка под массив память размером 32 ГБ #7
а мне говорили что можно выделить хоть сколько, если выделять кусками память
а как это, расскажите, будьте добры
karaulov6
15 / 15 / 1
Регистрация: 23.03.2013
Сообщений: 140
11.07.2013, 23:32     Выделите-ка под массив память размером 32 ГБ #8
ну для начала найдите 32гб ОЗУ (или сколько нужно для выделения 32 ГБ ?)
DU
1477 / 1053 / 45
Регистрация: 05.12.2011
Сообщений: 2,279
11.07.2013, 23:38     Выделите-ка под массив память размером 32 ГБ #9
не знаю делают ли так оси, но они могли бы так делать:
при выделении памяти, система где-то выделяет виртуальные адреса, которые мапаются на физическую память.
если выделилось больше, чем есть физической, то виртуальные адреса мапаются так, что при обращении к ним из физической памяти что-то свопается на диск (в случае нехватки физической памяти), и на освободившееся место в физическую память с диска подргужается то, что было засвоплено для страницы, в пределах которой процесс захотел обратится к ячейке. как-то так.
Ivan Fantom
 Аватар для Ivan Fantom
5 / 5 / 1
Регистрация: 12.10.2011
Сообщений: 75
11.07.2013, 23:40  [ТС]     Выделите-ка под массив память размером 32 ГБ #10
Цитата Сообщение от DU Посмотреть сообщение
странно что вы не словили исключение. или у вас есть 32 гигабайта?
может быть это из-за срезки. сигнатура оператора new [] такая:
void* operator new (std::size_t size) throw (std::bad_alloc);
если у вас 32 битка и не было срезки в unsigned long long, то будет при касте unsigned long long в std::size_t.
вопрос наверняка хитрый и такое решение в лоб - это врятли. что там могут быть за грабли - я даже не знаю.
если узнаете, расскажите плиз.
Вот и у меня возникает вопрос: почему исключение не вызвалось?
у меня 64 битка стоит

Есть такая вещь как свопинг, которая позволяет решить данную проблему путем переноса части памяти из ОЗУ на жесткий диск и осуществлением подкачки с диска обратно в ОЗУ при необходимости, но я никогда этим не занимался.
Прошу подскажите как это в плюсах реализвать можно для массива.
Maxim Prishchepa
Эксперт С++
 Аватар для Maxim Prishchepa
1761 / 984 / 60
Регистрация: 29.03.2010
Сообщений: 2,976
11.07.2013, 23:46     Выделите-ка под массив память размером 32 ГБ #11
на сколько я понимаю, первое что должно бросится в глаза это то, что 32 битная операционка может адресовать только грубо говоря 4 гб ОЗУ. т.к. на 32 никак, дальше к 64 разрядной, там все по честному 32 гб - копейки, едем дальше... как вариант можно нарезать слайсов из памяти, а дальше по необходимости их клеить как бог на душу положит, ибо в одну сплошную глыбу мне слабо верится... опять таки, если делать нарезку и хранить скажем указатели в листе, то проблем с добавление памяти не будет, в то время как если бы к примеру сделать вектор, то с большой долей вероятности не хватит памяти для выдиления нового куска, а если и хватит, то копировать все 32 гб на новое место - ой как не хорошо...
DU
1477 / 1053 / 45
Регистрация: 05.12.2011
Сообщений: 2,279
11.07.2013, 23:53     Выделите-ка под массив память размером 32 ГБ #12
вот тестик запустите:

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
#include <iostream>
#include <limits>
 
int main()
{
  std::cout << "max of unsigned long long = " << std::numeric_limits<unsigned long long>::max() << std::endl;
  std::cout << "max of std::size_t = " << std::numeric_limits<std::size_t>::max() << std::endl;
 
  unsigned long long size1 = 1024*1024*1024;
  size1 *= 32;
 
  //const unsigned long long size1 = 1ull << 35;
 
  const std::size_t size2 = size1;
  std::cout << "size1 = " << size1 << std::endl;
  std::cout << "size2 = " << size2 << std::endl;
 
//  char* ch = new char[size1]; // зайдите внутрь этого кода.
  // в 2012 студии вот что вызывается. т.е. тут size1 преобразуется в size_t
  // т.е. имеем срезку если сборка проекта 32 битная. а у вас какая там была?
  //void * operator new[]( size_t cb )
  //{
  //  void *res = operator new(cb);
  //  RTCCALLBACK(_RTC_Allocate_hook, (res, cb, 0));
  //  return res;
  //}
 
  return 0;
}
Kuzia domovenok
 Аватар для Kuzia domovenok
1882 / 1737 / 116
Регистрация: 25.03.2012
Сообщений: 5,907
Записей в блоге: 1
12.07.2013, 00:00     Выделите-ка под массив память размером 32 ГБ #13
Цитата Сообщение от DU Посмотреть сообщение
вот тестик запустите:
А чего его запускать? Лучше даже new не вызывать, а просто проверить, чему равен size в таком коде:
C++
1
unsigned long long size = 1024*1024*1024*32;
Оказывается, он тупо переполняется.
DU
1477 / 1053 / 45
Регистрация: 05.12.2011
Сообщений: 2,279
12.07.2013, 00:02     Выделите-ка под массив память размером 32 ГБ #14
переполняется, потому что 1024*1024*1024*32 - это перемножение интов. добавте везде ull и все будет ок.
полагаю автор специально сделал это в две строки а не в одну, как у вас.
Kuzia domovenok
 Аватар для Kuzia domovenok
1882 / 1737 / 116
Регистрация: 25.03.2012
Сообщений: 5,907
Записей в блоге: 1
12.07.2013, 00:10     Выделите-ка под массив память размером 32 ГБ #15
ОК, тогда такой вопрос. Почему оператор new и подобные ему функции (vector::resize, например) принимают размер типа size_t ? Я не знаю. Не знаю, он меньше ULL или нет.
Вроде как студия говорит, что size_t это 4 байта или unsigned int.
Тогда как же ULL передавать в качестве размера? (ULL в студии в два раза больше UINT и есть 8 байт)

Не по теме:

ULL это unsigned long long

DU
1477 / 1053 / 45
Регистрация: 05.12.2011
Сообщений: 2,279
12.07.2013, 00:14     Выделите-ка под массив память размером 32 ГБ #16
4 байта, если проект собирается в 32 битах.
если собирать 64 битный экзешник - то там sizeof(std::size_t) == sizeof(unsigned long long)
только пробовать выделять столько памяти не хочется. если начнется своп, то винда начнет жутко тупить. пусть автор пробует
Kuzia domovenok
 Аватар для Kuzia domovenok
1882 / 1737 / 116
Регистрация: 25.03.2012
Сообщений: 5,907
Записей в блоге: 1
12.07.2013, 00:18     Выделите-ка под массив память размером 32 ГБ #17
Ну вот и ответ. Где же мы возьмём ЭВМ 64 бита?
DU
1477 / 1053 / 45
Регистрация: 05.12.2011
Сообщений: 2,279
12.07.2013, 00:26     Выделите-ка под массив память размером 32 ГБ #18
сейчас новые 32 битные процы для персоналок поискать еще нужно. все давно уже 64 битное.
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
12.07.2013, 01:00     Выделите-ка под массив память размером 32 ГБ #19
Если собирать x64 проект, то исключение (bad_alloc), если 32 - тишина.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
12.07.2013, 01:21     Выделите-ка под массив память размером 32 ГБ
Еще ссылки по теме:

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

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

Или воспользуйтесь поиском по форуму:
Kuzia domovenok
 Аватар для Kuzia domovenok
1882 / 1737 / 116
Регистрация: 25.03.2012
Сообщений: 5,907
Записей в блоге: 1
12.07.2013, 01:21     Выделите-ка под массив память размером 32 ГБ #20
Цитата Сообщение от alsav22 Посмотреть сообщение
Если собирать x64 проект, то исключение (bad_alloc), если 32 - тишина.
Очевидно, в 32хбитном проекте при вызове new char[size] происходит приведение типов,
size_t при win32 означает тип unsigned int.
т.е. идёт приведение "длиннодлинного" size=1024ull*1024ull*1024ull*32ull; к типу unsigned int. После приведения в new передаётся НОЛЬ(!) в 32хбитных системах.
О чём мы тут и болтали.
Yandex
Объявления
12.07.2013, 01:21     Выделите-ка под массив память размером 32 ГБ
Ответ Создать тему
Опции темы

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