2016-08-02 2 views
1

Я пытаюсь зарезервировать место для вектора векторов, но он не работает и выдает следующее сообщение об ошибке:Выделение памяти для вектора векторов

terminate called after throwing an instance of 'std::bad_alloc' 
    what(): std::bad_alloc 

Каждый раз, когда я использую достаточно большое количество , Минимальная версия, что я ниже:

#include <vector> 
#include <iostream> 
using namespace std; 


int main(){ 

    int base; 
    cout << "Enter Base: "; 
    cin >> base; 

    int dimension; 
    cout << "Enter Dimension: "; 
    cin >> dimension; 

    int perms = 1; 
    for(int i=0; i<dimension; i++){ 
    perms *= base; 
    } // This gets the number of permutations with repetition 

    int length; 
    cout << "Enter Length: "; 
    cin >> length; 

    float structSize = 1.0; 

    for(float i=0.0; i<length; i++){ 
    structSize *= perms-i; 
    structSize /= (i+1.0); 
    } // This gets the number of combinations 

    vector< vector< vector<double> > > allStructs; 
    allStructs.reserve(structSize); 

    return 0; 
} 

Он должен работать на больших structSizes, но терпит неудачу на базе = 3, размер = 4, длина = 6, что делает structSize = 324,540,216. Возможно ли, чтобы это работало?

+2

Да, возможно - добавьте больше памяти на ваш компьютер. – Slava

+2

Сделал ли вы математику, сколько памяти потребуется? –

+0

Вы действительно хотите сохранить каждый результат? Вы не можете просто перебрать результат? – Jarod42

ответ

5

Вам нужно подумать о вашем использовании памяти.

It should work for large structSizes, but fails at base=3, dimension=4, length=6 which makes structSize=324,540,216. Is it possible for this to work?

Так что вы делаете, на абстрактном уровне, выделяет структуру данных, которая содержит 324,540,216 экземпляры vector<vector<double>> объекта.

Вот что мы знаем о vector объекты:

  • Его размер должен быть не менее 16 байт; он должен хранить указатель, который в 64-битной архитектуре, вероятно, 8 байтов, и ему нужно сохранить размер, который, вероятно, также будет 8 байтов.
  • Его размер, вероятно, будет значительно больше, так как с момента создания экземпляра последнего объекта vector<double> он будет потреблять еще один [по меньшей мере-] 16 байт при каждом его создании.

Так что на первый взгляд, ваш вызов allStructs.reserve(structSize) выделяет 5 гигабайт. Вероятно, это больше выделяется, так как размер метаданных вектора может быть больше 16 байт.

+0

Технически, размер вектора не ограничен, если все, что он хранит, является индексом в векторном массиве в другом месте. Даже на более реалистичной стороне я увидел реализацию 'std :: string', когда внутренний указатель указал на данные, и сохранил размер и емкость в mData [-4] и mData [-8], что означало, что 'printf ("% s ", myStdString)' будет работать. –

+0

@MooingDuck Fair point, хотя он все равно будет вызывать проблемы с распределением памяти в тот момент, когда пользователь попытался фактически сохранить и работать со значениями в каждом из этих индексов. – Xirema

2

Объявите свой StructSize как double StructSize = 1.0;, тогда он должен «логически« работа.

Однако reserve() может не работать из-за возможных ограничений на вашем компьютере.

Смежные вопросы