код бросает std :: bad_alloc, недостаточно памяти или это может быть ошибкой? - PullRequest
2 голосов
/ 14 мая 2010

Я занимаюсь синтаксическим анализом с довольно большой грамматикой (1,1 ГБ, это анализ данных).Говорят, что используемый мной синтаксический анализатор (bitpar) оптимизирован для весьма неоднозначных грамматик.Я получаю эту ошибку:

1terminate called after throwing an instance of 'std::bad_alloc'
  what():  St9bad_alloc
dotest.sh: line 11: 16686 Aborted                 bitpar -p -b 1 -s top -u unknownwordsm -w pos.dfsa /tmp/gsyntax.pcfg /tmp/gsyntax.lex arbobanko.test arbobanko.results

Есть ли надежда?Означает ли это, что у него закончилась память?Он использует около 15 ГБ, прежде чем он падает.Машина, которую я использую, имеет 32 ГБ оперативной памяти, а также подкачку.Сбой перед выводом одного дерева разбора;Я думаю, что он вылетает после чтения грамматики, во время попытки построить анализ диаграммы для первого предложения.

Анализатор - эффективный анализатор диаграммы CYK, использующий представления битовых векторов;Я предполагаю, что это уже довольно эффективно для памяти.Если это действительно требует слишком много памяти, я мог бы выбрать из правил грамматики, но это, конечно, снизит точность разбора.

Я думаю, что проблема, вероятно, в том, что у меня очень много нетерминалов,вероятно, попытайтесь найти другой анализатор (какие-либо предложения?)

ОБНОВЛЕНИЕ: ради потомков, я нашел проблему давным-давно.Грамматика была слишком большой из-за ошибки, поэтому парсер не мог справиться с ней с доступной памятью.С правильной грамматикой (которая на порядок меньше) она отлично работает.

Ответы [ 2 ]

4 голосов
/ 14 мая 2010

Возможно, что память становится фрагментированной. Это означает, что ваша программа может не выделить 1 КБ, даже если 17 ГБ памяти свободно, когда эти 17 ГБ фрагментированы на 34 миллиона свободных фрагментов по 512 байт каждый.

Конечно, есть вероятность, что ваша программа неправильно рассчитала распределение памяти. Распространенной ошибкой является попытка выделить -1 байт памяти. Поскольку объемы памяти всегда положительны, это интерпретируется как size_t(-1), намного больше 32 ГБ. Но на самом деле нет факта, который указывает в этом направлении.

Чтобы решить эту проблему, вам понадобится кто-то, кто говорит на C ++. Если это действительно фрагментация памяти, хороший программист на C ++ может адаптировать стратегию выделения памяти в соответствии с вашими конкретными потребностями. Некоторые стратегии включают в себя хранение объектов одного размера и замену строки на прокладки.

0 голосов
/ 14 мая 2010

Если ваше приложение использует 32-битную модель памяти, то каждый процесс получит 4 ГБ виртуального адресного пространства. Из которых только 2G доступно для пользовательского пространства.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...