@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) ()
  • Вопрос задан
  • 15099 просмотров
Пригласить эксперта
Ответы на вопрос 3
jcmvbkbc
@jcmvbkbc
"I'm here to consult you" © Dogbert
Ну а я повторю свой оригинальный ответ: без полного исходного текста можно сказать только то, что ошибка, скорее всего, где-то в другом месте. И замена объектов ссылками просто замаскировала проблему на время.

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

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

Похожие вопросы