Включая огромную строку в наши программы на С++?
Я пытаюсь включить огромную строку в мои С++-программы, ее размер составляет 20598617 символов, я использую #define
для ее достижения. У меня есть файл заголовка, содержащий этот оператор
#define "<huge string containing 20598617 characterd>"
Когда я пытаюсь скомпилировать программу, я получаю ошибку как fatal error C1060: compiler is out of heap space
Я пробовал следующие параметры командной строки без успеха
/Zm200
/Zm1000
/Zm2000
Как я могу сделать успешную компиляцию этой программы?
Платформа: Windows 7
Ответы
Ответ 1
Вы не можете, не надежно. Даже если он будет компилироваться, он может сломать библиотеку времени выполнения или предположения ОС и т.д.
Если вы сообщите нам, почему вы пытаетесь это сделать, мы можем предложить лоты альтернатив. Решение о том, как обрабатывать сколь угодно большие данные, является основной частью программирования.
Отредактировано для добавления:
Вместо того, чтобы догадываться, я просмотрел MSDN:
До смежных строк, являющихся конкатенированный, строка не может быть более 16380 однобайтовых символы.
Строка из Юникода около половины эта длина также ошибка.
На странице завершается:
Возможно, вы захотите хранить исключительно большие строковые литералы (32 КБ или более) в пользовательский ресурс или внешний файл.
Что говорят другие компиляторы?
Далее отредактирован, чтобы добавить:
Я создал такой файл:
char s[] = {'x','x','x','x'};
Я продолжал удваивать вхождения 'x'
, тестируя каждый как файл #include
.
Успешная строка байта 8388608; Ошибка 16777216 байт с ошибкой "из области кучи".
Ответ 2
Я подозреваю, что вы используете лимит дизайна для размера символьной строки.
Большинство людей действительно думают, что миллион символов достаточно длинный: -}
Чтобы избежать таких ограничений дизайна, я постараюсь не превращать все это в одну литеральную строку. По подозрению в том, что #define макрос тела аналогичным образом имеют аналогичные ограничения, я также стараюсь не ставить все это в один #define.
Большинство компиляторов C будут принимать довольно большие списки отдельных символов в качестве инициализаторов. Если вы пишете
char c[]={ c1, c2, ... c20598617 };
когда c_i является вашим индивидуальным символом, вы можете добиться успеха. Я видел приложения GCC2, в которых было 2 миллиона таких элементов (они были загружены некоторым типом ROM-образа). Возможно, вы даже сможете сгруппировать c_i в блоки из K символов для K = 100, 1000, 10000, что соответствует вашим вкусам, и это может реально помочь компилятору.
Вы также можете рассмотреть возможность запуска вашей строки с помощью алгоритма сжатия,
помещая сжатый результат в ваш файл С++ любым из указанных выше способов,
и распаковка после загрузки программы.
Я подозреваю, что вы можете получить алгоритм декомпрессии в несколько тысяч байт.
Ответ 3
Um, сохраните строку в отдельном ресурсе какого-либо типа и загрузите его? Серьезно, во встроенных землях вы будете иметь это как отдельный ресурс и не удерживать его в ОЗУ. В Windows я полагаю, что вы можете использовать DLL или другие внешние ресурсы для обработки этого для вас. Компиляторы не предназначены для хранения такого размера ресурсов для вас, и они потерпят неудачу.
Ответ 4
Сохраните строку в файле и просто откройте и прочитайте ее...
Его намного более чистый/организованный таким образом [я предполагаю, что прямо сейчас у вас есть файл с именем blargh.h, который содержит этот #Define...]
Ответ 5
Увеличьте пространство кучи компилятора.
Ответ 6
Если ваша строка получена из большого текстового или двоичного файла, вам может повезти с помощью команды xxd -i
(чтобы получить все в массиве, на ответ Иры Бакстер) или вариант команды bin2obj
(для получить все в файл .o
, который вы можете связать с программой).
Обратите внимание, что в этом случае строка не может быть завершена нулем.
См. ответы на более ранний вопрос: Как я могу получить содержимое файла во время сборки в моей строке С++?
(Кроме того, в качестве примечания: обратите внимание на существование .xbm
format.)
Ответ 7
Это очень старый вопрос, но пока нет окончательного ответа: С++ 11 raw string литералы, похоже, выполняют эту работу.
Это хорошо компилируется на GCC 4.8:
#include <string>
std::string data = R"(
... <1.4 MB of base85-encoded string> ...
)";
Как сказано в других сообщениях в этом потоке, это определенно не является предпочтительным способом обработки больших объемов данных.