2015-06-24 2 views
3

В моих модульных тестах я получаю следующее сообщение об ошибке компилятора:Как избежать «предела компилятора: переполнение стека компилятора» с большими векторами?

The error message indicates as follows: 
'fatal error C1063: compiler limit: compiler stack overflow' 

Это вызвано некоторыми сгенерированных заголовками, которые содержат:

std::vector<unsigned char> GetTestData() 
{ 
    return { 0x1, 0x2, 0x3 }; // Very large 500kb of data 
} 

Как я могу использовать векторы, таким образом, без сбоев MSVC? Обратите внимание, что код строит ОК в clang и gcc.

+1

500k целочисленного литерала? – user3528438

+1

Почему вы не делаете разумную вещь, добавляя данные к вектору внутри функции и, таким образом, просто возвращаете вектор? – PaulMcKenzie

+0

Я думаю, что это не должно быть в коде. не можете ли вы сериализовать данные во внешний файл и deseriealize его во время выполнения в кусках? Я думаю, что это лучший подход. –

ответ

4

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

std::vector<unsigned char> GetTestData() 
{ 
    static const unsigned char data[] = { 
     0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0x0, 
      ... 
    }; // Very large 500kb of data 

    return std::vector<unsigned char>(data, data + sizeof(data)); 
} 

EDIT: Спасибо Лундин за указание о Уст.

+0

ваш ответ побеждает над знаками, потому что без статического ключевого слова требуется 1 час для компиляции! – paulm

+1

Опцией может быть генерация данных во время выполнения, а не для жесткого кода каждой записи. –

+0

@paulm. Если это программа Windows, правильный способ сделать это - разместить данные в ресурсах вашей программы и заполнить вектор из этих ресурсов. Посмотрите 'RCDATA' и его использование. – PaulMcKenzie

-1

Даже если он строит штраф в clang и gcc, я бы не рекомендовал возвращать большие векторы, подобные этому по значению. Если данные, которые вы работаете неизменен я бы вернуть его в качестве константной ссылки как:

// EDIT Moved vector outside of function 
static const std::vector<unsigned char> static_v({ 0x1, 0x2, 0x3 }); 
    const std::vector<unsigned char> & GetTestData() 
    { 
    return static_v; 
    } 
+2

Что-то не так, полагаясь на операции перемещения? Они были официальными в течение 4 лет. – Angew

+1

@Angew Абсолютно ничего. Но возвращение статической ссылки на константу, по крайней мере, гарантирует, что конструктор с временным потреблением <...> получает вызов только один раз. Если вам нужен изменяемый вектор <...>, вы можете позже вызывать 'vector <...> vv = GetTestData()', который генерирует временную копию (время) и вызывает семантику перемещения для вас. – Oncaphillis

+0

По какой-то причине этот способ сделать это по-прежнему вызывает сбой компилятора – paulm

1

Попробуйте построить большой массив для инициализации, а не с помощью инициализатора непосредственно.

std::vector<unsigned char> GetTestData() 
{ 
    static const unsigned char init[] = { 0x1, 0x2, 0x3 }; // Very large 500kb of data 
    return std::vector<unsigned char>(std::begin(init), std::end(init)); 
} 
+0

Это может легко переполнить стеки времени выполнения, не так ли? – Angew

+0

Действительно. Не делая это 'static const' просто перемещает переполнение стека из компилятора в приложение ... – Lundin

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