Странное исключение с плавающей точкой c ++ (присваивание указателя) - PullRequest
0 голосов
/ 14 апреля 2020

Я хочу создать древовидную структуру, но на основе unordered_map тем. Короче говоря, я хочу создать дерево топи c, и я подумал об этом подходе:

typedef struct topic_tree {
    int id;
    unordered_map<string, struct topic_tree *> children;
} topic_tree;

Это звучит как довольно хорошая идея, потому что для каждого "топи c" я бы имел идентификатор для него (или того, что мне нужно), и из каждого узла будет карта от следующей строки до следующего дерева темы и т. д.

Я попытался создать это дерево: first/second/third. Это означает, что сначала он является родителем второго, а второй - родителем третьего. Могут быть и другие вещи, например first/forth/fifty, это означает, что у первого теперь есть 2 ребенка, второго и четвертого ... это объяснение. Теперь давайте перейдем к проблеме:

Например, я объявляю это:

topic_tree *root = (topic_tree *)malloc(sizeof(struct topic_tree));
root->id = -1;
topic_tree *x = (topic_tree *)malloc(sizeof(struct topic_tree));
x->id = 5;
root->children["first"]=x;

но это: root->children["first"] = x; дает мне Floating point exception, и я понятия не имею, почему ..

1 Ответ

2 голосов
/ 14 апреля 2020

Причина в том, что после выделения структуры topic_tree вы не инициализируете ее.
Таким образом, std::unordered_map работает с неинициализированной памятью, которая не работает.

Лучшее решение с использованием new / delete

Как правило, в приложении C ++ следует избегать использования malloc / free. Вместо этого используйте операторы new и delete, которые будут автоматически вызывать конструктор объекта при построении,
и деструктор при удалении.
При размещении узлов таким образом: new topic_tree{} у вас все будет хорошо.

Если вам требуется для использования malloc / free

Если вы хотите придерживаться значения mallo c, вы должны явно вызвать Конструктор.
Это может быть сделано так:

new (root) topic_tree{};

Но помните, чтобы free объект, который вы должны вызвать деструктор!

root->~topic_tree();

Внимание : Если вы видите это в своем коде, это обычно запах кода!
Для него очень мало приложений!

Современное решение (Управление памятью с помощью интеллектуальных указателей)

В современных проектах на C ++ вы вообще почти не видите никаких операторов new или delete.
Вместо этого для выделения объектов вы используете умные указатели, такие как
std::unique_ptr или std::shared_ptr (также std::auto_ptr, но немного по-другому).
Эти контейнеры будут автоматически управлять временем жизни объектов, поэтому вам не придется об этом беспокоиться.

...