@byulent

Ошибка std::bad_alloc — из-за чего?

Опять та же самая программа и те же классы tree:
class tree{
private:
	vector<node> nodes;
	vector<wstring> codedString;
	int fmax;
	int inode1;
	int inode2;
public:
	void extractString(wstring& str); //Разделяем строку на первичные узлы
	void construct();
	void codeString (wstring& str);
	void printCodedString();
	int getCodedStringSize();
	void printFreqTable();
	void printCodeTable();
	void codeNodes();
	void code(node& n, int level);
	void selectNode (wstring& str);
	wstring decodeString ();
	void findCode (wstring& str);
	node findNode (wstring& code);
	bool inNodes (wstring& str);
	bool inNodes (int freq);
	void getMinNode1();
	void getMinNode2();
};

и node:
class node{
private:
	int freq, child1, child2;
	wstring sym;
	wstring code;
	bool flag;
public:
	node(int fr, int ch1, int ch2, wstring s, wstring c):freq(fr),child1(ch1),child2(ch2),sym(s),code(c),flag(false){};
	int getFreq();
	int getChild1();
	int getChild2();
	wstring getCode();
	//bool getFlag();
	wstring getSym();
	void incFreq();
	void incCode(int val);
	void setCode(wstring &str);
	void toggle();
	//bool operator> (node& n);
	bool operator<= (node& n);
};


Правда, теперь вопрос уже посвящён другим функциям - функциям, присвающим каждому узлу опеределённый код, состоящий из 0 и 1:
void tree::codeNodes()
{
	//wcout << L"кодируются вершины" << endl;
	code(nodes[nodes.size()-1], 0);
	//wcout << L"вершины закодированы" << endl;
}

void tree::code(node& n, int level)
{
	int ch1 = n.getChild1();
	int ch2 = n.getChild2();
	wstring tmp=n.getCode();
	//wcout<<tmp<<endl;
	nodes[ch1].setCode(tmp);
	nodes[ch1].incCode(0);
	nodes[ch2].setCode(tmp);
	nodes[ch2].incCode(1);
	if (ch1!=-1&&ch2!=-1) {
		//wcout<<L"глубина "<<level<<endl;
		code (nodes[ch1], level+1);
		code (nodes[ch2], level+1);
	}
}

void node::incCode (int val)
{
	//wcout << L"добавляем к коду символ" << endl;
	wstringstream s;
	s << val;
	code += s.str();
}

void node::setCode (wstring &str){
	code += str;
}


Так вот, маленькие строки успешно кодируются. Но на строках большей длины программа ведёт себя так:
Введите строку
Говорил командир про полковника и про полковницу,про подполковника и про подполковницу, про поручика и про поручицу, про подпоручика и про подпорутчицу, про прапорщика и про прапорщицу, про подпрапорщика, а про подпрапорщицу молчал.
//...
//...
Размер строки:7424
terminate called after throwing an instance of 'std::bad_alloc'
  what():  std::bad_alloc

Откуда это берётся? Памяти вроде расходуется не так уж и много...
Бэктрейс отладчика:
#0  0x00007ffff74ab267 in __GI_raise (sig=sig@entry=6)
    at ../sysdeps/unix/sysv/linux/raise.c:55
#1  0x00007ffff74aceca in __GI_abort () at abort.c:89
#2  0x00007ffff7ae6b7d in __gnu_cxx::__verbose_terminate_handler() ()
   from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#3  0x00007ffff7ae49c6 in ?? () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#4  0x00007ffff7ae4a11 in std::terminate() ()
   from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#5  0x00007ffff7ae4c29 in __cxa_throw ()
   from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#6  0x00007ffff7ae51cc in operator new(unsigned long) ()
   from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#7  0x00007ffff7b8a869 in std::__cxx11::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >::_M_mutate(unsigned long, unsigned long, wchar_t const*, unsigned long) () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#8  0x00007ffff7b8bcdb in std::__cxx11::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >::_M_append(wchar_t const*, unsigned long) ()
   from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#9  0x0000000000402501 in node::setCode(std::__cxx11::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >) ()
#10 0x0000000000403577 in tree::code(node&, int) ()
#11 0x000000000040366c in tree::code(node&, int) ()
#12 0x00000000004036a7 in tree::code(node&, int) ()
  • Вопрос задан
  • 14316 просмотров
Пригласить эксперта
Ответы на вопрос 3
jcmvbkbc
@jcmvbkbc
"I'm here to consult you" © Dogbert
Ну а я повторю свой оригинальный ответ: без полного исходного текста можно сказать только то, что ошибка, скорее всего, где-то в другом месте. И замена объектов ссылками просто замаскировала проблему на время.

Хотя у меня есть одно предположение: возможно вы неправильно строите дерево и некоторые его узлы являются своими собственными детьми.
Ответ написан
Комментировать
@AM5800
Если маленькие объекты выделяются, а большие нет. И при этом память точно не закончилась - то самая вероятная причина - фрагментирование кучи.
Самый простой способ решить эту проблему - всегда компилироваться в x64.
Ответ написан
maaGames
@maaGames
Погроммирую программы
Убедись, что нет вечной рекурсии, которая всю память сжирает. Функцию tree:code изучи. Может счётчик рекурсии поставить, посмотреть значение при падении или просто запретить слишком глубокую рекурсию.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы