Переменные C ++ больше стека (переполнение стека)

0

Мне нужно создать такой массив

double grid [15000][40];

но стек в Visual Studio 2012 составляет всего 1 МБ. Как я могу использовать переменные вроде этого или больше? Это означает, что если я создаю

std::vector<int>

и я push_back 600 000 раз идет в переполнение стека? Это кажется большим ограничением, как можно решить? Заранее спасибо.

  • 4
    Содержимое std::vector не находится в стеке.
  • 0
    Я не вижу, как .NET или Java-теги актуальны здесь.
Показать ещё 2 комментария
Теги:
stack-overflow

5 ответов

3
Лучший ответ

Большие объекты должны иметь статическую или динамическую память.

Статическая:

int a[1000000];

void f()
{
    a[3] = 12;    // fine
}

Остерегайтесь общих, одновременных доступов к статической памяти.

Динамический (но правильно управляемый подходящим классом) :

void f()
{
    std::vector<int> a(1000000);   // dynamic objects managed by std::vector
    a[3] = 12;
}

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

2

Здесь нет проблем.

Это означает, что если я создам std :: vector, а я push_back 600 000 раз, то он перейдет в переполнение стека? Это кажется большим ограничением

Нет, потому что элементы векторов не имеют автоматической продолжительности хранения (они не "живут в стеке"). Они не могли.

как можно решить

Нечего решать. Векторные элементы динамически распределяются.

  • 0
    Я хотел бы использовать «двойную сетку [15000] [40]», а не вектор, как я могу это сделать?
  • 2
    @ user3343783: Если вы хотите это в стеке: (a) нет, вы не делаете (b) вы не должны (c) вы не можете (d) не делать этого. Вы можете обойти это с помощью static объекта, но я все еще не стал бы.
Показать ещё 9 комментариев
0

память вектора выделена в кучу, вам не нужно беспокоиться о стеке. Вместо push_back вы можете использовать размер функции-члена:

 std::vector<int> grid;
 grid.resize(15000*40);

или даже лучше, вы можете использовать уникальный указатель, если сетка имеет фиксированный размер

0

Вы можете определить этот массив как

static double grid [15000][40];

Что касается std::vector то он выделяет память для своих элементов в куче не в стеке.

0

Если вы не хотите использовать std::vector по любой причине, альтернативное решение:

int main()
{
  int (*grid)[40] = new int[15000][40];

  // work with grid
  grid[0][0] = 0.0;
  grid[14999][39] = 42;

  delete [] grid;
}

Обычные оговорки применяются в отношении необработанных указателей на динамическое хранилище, что приводит к утечкам памяти, если область действия заканчивается исключением, так что delete никогда не выполняется.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню