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

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

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

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

11.07.2013, 22:45. Просмотров 2486. Ответов 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 ГБ  
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
11.07.2013, 22:45     Выделите-ка под массив память размером 32 ГБ
Посмотрите здесь:
C++ Динамически выделить память под массив
C++ Динамически выделить память под массив
Динамически выделить память под массив функций C++
Выделить и удалить память под 4 мерный массив C++
C++ Выделить память под динамический массив указателей
Как выделяется память под массив string? C++
C++ Выделить память под массив размера 2^64 байтов
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
coloc
погромист
409 / 245 / 15
Регистрация: 27.08.2012
Сообщений: 550
Завершенные тесты: 1
11.07.2013, 22:48     Выделите-ка под массив память размером 32 ГБ #2
через вектор попробуйте
Kuzia domovenok
1889 / 1744 / 117
Регистрация: 25.03.2012
Сообщений: 5,922
Записей в блоге: 1
11.07.2013, 22:53     Выделите-ка под массив память размером 32 ГБ #3
чего-то я не вижу связи между вопросом и кодом. Плохо гляжу?
Вопрос про "размер выделяемой памяти должен составлять = 235 байт"
Код про "size = 32*1024*1024*1024;"
Так вопрос про 235 байт или 32 Гб?
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
Сообщений: 172
11.07.2013, 23:25     Выделите-ка под массив память размером 32 ГБ #5
может там ошиблись и нужно 32 метра? ну могу только удачи пожелать с 32 ГБ
DU
1480 / 1056 / 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
9 / 9 / 2
Регистрация: 05.07.2013
Сообщений: 86
11.07.2013, 23:29     Выделите-ка под массив память размером 32 ГБ #7
а мне говорили что можно выделить хоть сколько, если выделять кусками память
а как это, расскажите, будьте добры
karaulov6
15 / 15 / 1
Регистрация: 23.03.2013
Сообщений: 172
11.07.2013, 23:32     Выделите-ка под массив память размером 32 ГБ #8
ну для начала найдите 32гб ОЗУ (или сколько нужно для выделения 32 ГБ ?)
DU
1480 / 1056 / 45
Регистрация: 05.12.2011
Сообщений: 2,279
11.07.2013, 23:38     Выделите-ка под массив память размером 32 ГБ #9
не знаю делают ли так оси, но они могли бы так делать:
при выделении памяти, система где-то выделяет виртуальные адреса, которые мапаются на физическую память.
если выделилось больше, чем есть физической, то виртуальные адреса мапаются так, что при обращении к ним из физической памяти что-то свопается на диск (в случае нехватки физической памяти), и на освободившееся место в физическую память с диска подргужается то, что было засвоплено для страницы, в пределах которой процесс захотел обратится к ячейке. как-то так.
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
Эксперт С++
1920 / 1032 / 74
Регистрация: 29.03.2010
Сообщений: 3,167
11.07.2013, 23:46     Выделите-ка под массив память размером 32 ГБ #11
на сколько я понимаю, первое что должно бросится в глаза это то, что 32 битная операционка может адресовать только грубо говоря 4 гб ОЗУ. т.к. на 32 никак, дальше к 64 разрядной, там все по честному 32 гб - копейки, едем дальше... как вариант можно нарезать слайсов из памяти, а дальше по необходимости их клеить как бог на душу положит, ибо в одну сплошную глыбу мне слабо верится... опять таки, если делать нарезку и хранить скажем указатели в листе, то проблем с добавление памяти не будет, в то время как если бы к примеру сделать вектор, то с большой долей вероятности не хватит памяти для выдиления нового куска, а если и хватит, то копировать все 32 гб на новое место - ой как не хорошо...
DU
1480 / 1056 / 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
1889 / 1744 / 117
Регистрация: 25.03.2012
Сообщений: 5,922
Записей в блоге: 1
12.07.2013, 00:00     Выделите-ка под массив память размером 32 ГБ #13
Цитата Сообщение от DU Посмотреть сообщение
вот тестик запустите:
А чего его запускать? Лучше даже new не вызывать, а просто проверить, чему равен size в таком коде:
C++
1
unsigned long long size = 1024*1024*1024*32;
Оказывается, он тупо переполняется.
DU
1480 / 1056 / 45
Регистрация: 05.12.2011
Сообщений: 2,279
12.07.2013, 00:02     Выделите-ка под массив память размером 32 ГБ #14
переполняется, потому что 1024*1024*1024*32 - это перемножение интов. добавте везде ull и все будет ок.
полагаю автор специально сделал это в две строки а не в одну, как у вас.
Kuzia domovenok
1889 / 1744 / 117
Регистрация: 25.03.2012
Сообщений: 5,922
Записей в блоге: 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
1480 / 1056 / 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
1889 / 1744 / 117
Регистрация: 25.03.2012
Сообщений: 5,922
Записей в блоге: 1
12.07.2013, 00:18     Выделите-ка под массив память размером 32 ГБ #17
Ну вот и ответ. Где же мы возьмём ЭВМ 64 бита?
DU
1480 / 1056 / 45
Регистрация: 05.12.2011
Сообщений: 2,279
12.07.2013, 00:26     Выделите-ка под массив память размером 32 ГБ #18
сейчас новые 32 битные процы для персоналок поискать еще нужно. все давно уже 64 битное.
alsav22
5416 / 4812 / 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 ГБ
Еще ссылки по теме:
C++ Выделить память под массив неизвестной длины
C++ Как выделить память под массив в структуре?
C++ Почему не очищает память, выделенную под массив структур
Выделить память под массив в 100500 индексе. Возможно ли? C++
C++ Не могу удалить динамически выделенную память под массив

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

Или воспользуйтесь поиском по форуму:
Kuzia domovenok
1889 / 1744 / 117
Регистрация: 25.03.2012
Сообщений: 5,922
Записей в блоге: 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 ГБ
Ответ Создать тему
Опции темы

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