#c #memory #tree
#c #память #дерево
Вопрос:
Я сталкиваюсь с ошибкой сегментации при попытке создать слишком большое дерево. Если tree_size = 10000, программа работает нормально, но когда tree_size = 100000, программа завершает работу непосредственно перед последней строкой (т. е. после инструкции печати «Готово»).
Мне кажется, что tree_size, равный 100 000, не должен быть таким большим, поэтому я был бы удивлен, если бы на моем компьютере закончилась память или что-то в этом роде. Ошибка сегментации связана с кодом или моим компьютером?
Это код, который я использую:
#include <iostream>
#include <memory>
#include <vector>
template<class T> using sp = std::shared_ptr<T>;
template<class T> using wp = std::weak_ptr<T>;
struct Node: public std::enable_shared_from_this<Node>
{
std::string value;
std::vector<sp<Node> > children;
wp<Node> parent;
Node(std::string value, const wp<Node>amp; parent = wp<Node>())
: value {value}
, children {std::vector<sp<Node>>()}
, parent {wp<Node>()}{}
sp<Node> AddLeaf(const std::stringamp; value)
{
sp<Node> newLeaf = std::make_shared<Node>(value, shared_from_this());
this->children.emplace_back(std::move(newLeaf));
return this->children.back();
}
};
int main(int argc, char * argv[])
{
int tree_size = 100000;
sp<Node> root = std::make_shared<Node>(std::to_string(0));
sp<Node> current = root;
for(int i = 1; i < tree_size; i)
{
current->AddLeaf(std::to_string(i));
current = current->children[0];
}
std::cout << "Finished" << std::endl;
return 0;
}
При отладке в XCode я получаю сообщение об ошибке «Поток 1: EXC_BAD_ACCESS [code=2, address=0x7fff5f3ffff8]».
Комментарии:
1. На первый взгляд, я предполагаю, что у вас заканчивается стек из-за слишком глубокой рекурсии. Корневой
Node
деструктор вызывает деструкторы каждогоNode
элементаchildren
, которые, в свою очередь, вызывают деструкторы своих дочерних элементов и так далее.2. Да, классическая проблема. Вам пришлось бы написать деструктор самостоятельно.
3. Создаваемое вами «дерево» на самом деле представляет собой односвязный список длиной в 100 000 элементов. Когда
root
выходит за пределы области видимости, это запускает рекурсию глубиной 100 000 уровней. Это не сработает — стек выполнения является ограниченным ресурсом.4. Спасибо, есть идеи, как я могу обойти ограничение стека в подобных случаях?