C ++, как получить доступ к переменной структуры указателя - PullRequest
0 голосов
/ 05 июня 2019

Я пытаюсь скопировать двоичное дерево, где узлы имеют структуру в своем классе Node. Я не могу понять, почему он падает при установке строки bookName. Он продолжает падать. Переходя в режим отладки, он говорит, что не может видеть ссылочный номер или не может прочитать строку.

#include <iostream>
#include <string>
using namespace std;

struct Book {
    string name;
};
struct TreeNode {
    float key;
    Book book;
    TreeNode* leftPtr;
    TreeNode* rightPtr;
};
class MyTree {
    TreeNode* rootPtr;
    // this function crashes!
    TreeNode* makeNode(float key,string bookName) {
        TreeNode* newNode = (TreeNode*)malloc(sizeof(TreeNode));
        if (newNode == NULL) {
            cout << "Error: No more space";
        }
        else {
            newNode->key = key;
            cout << newNode->book.name << endl;
            newNode->book.name = bookName;// CRASHES HERE
            cout << "Name: " << newNode->book.name;
            newNode->leftPtr = NULL;
            newNode->rightPtr = NULL;
        }
        return newNode;
    }
    TreeNode* insert(TreeNode* nodePtr, float key, string bookName) {
        if (nodePtr == NULL) {
            nodePtr = makeNode(key, bookName);
        }
        else if (key < nodePtr->key) {
            nodePtr->leftPtr = insert(nodePtr->leftPtr, key, bookName);
        }
        else if (key > nodePtr->key) {
            nodePtr->rightPtr = insert(nodePtr->rightPtr, key, bookName);
        }
        else { cout << "Error: Key already exist. Cannot add node."; }
        return nodePtr;
    }
public:
    MyTree() { rootPtr = NULL; }
    void addNode() {
        // ask for input
        float key = 0; string bookName = "default";
        cout << "Enter a value for the key: ";
        cin >> key;
        cout << "Enter the name for the book: ";
        cin >> bookName;

        // insert
        rootPtr = insert(rootPtr, key, bookName);
    }
};
int main() {
    MyTree a;
    a.addNode();
}

Сообщение об ошибке отладки таково:

Exception thrown at 0x0121DA2E in Assessment.exe: 0xC0000005: Access violation reading location 0xCDCDCDCD.

Пожалуйста, помогите


Редактировать 1: Заменил malloc как предложено, но он вылетает при установке переменной key.

TreeNode* makeNode(float key,string bookName) {
        cout << "Here";
        TreeNode* newNode = new TreeNode;// CRASHES HERE
        cout << "Here";
        if (newNode == NULL) {
            cout << "Error: No more space";
        }
        else {
            newNode->key = key;
            newNode->book.name = bookName;
            cout << "Name: " << newNode->book.name;
            newNode->leftPtr = NULL;
            newNode->rightPtr = NULL;
        }
        return newNode;
    }

Ответы [ 2 ]

3 голосов
/ 05 июня 2019

Если вы немного поищите шаблон 0xCDCDCDCD, вы быстро обнаружите, что именно эта отладочная сборка malloc использует для заполнения памяти, которую она выделяет. Это, в свою очередь, означает, что вы используете неинициализированную память в своей программе. Вы выделяете память с помощью malloc, но не инициализируете память.

И это распределение с malloc является основной причиной вашей проблемы. Функция malloc выделяет память, но не вызывает конструкторов объектов. Это, в свою очередь, означает, что объект std::string структуры Book не создан, и его использование каким-либо образом приводит к неопределенному поведению .

Решение, помимо чтения хороших книг по C ++ и правильного изучения C ++, заключается в использовании оператора new для выделения вашего объекта:

TreeNode* newNode = new TreeNode;
1 голос
/ 05 июня 2019
TreeNode* newNode = (TreeNode*)malloc(sizeof(TreeNode));

Не делай этого.Ваш TreeNode содержит std::string, который должен быть правильно инициализирован.С malloc вы ничего не инициализируете, вы просто выделяете память.Поэтому, когда вы пытаетесь использовать строку, она, скорее всего, находится в каком-то недопустимом состоянии и не вызовет ничего, кроме проблем.Существует не так много причин использовать malloc в C ++, лучше просто сделайте это вместо:

TreeNode* newNode = new TreeNode;

И когда это больше не нужно, выполните delete newNode;.

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