Данные векторных элементов повреждены после действия find () - PullRequest
1 голос
/ 19 мая 2019

Я создаю компилятор с использованием C ++.Во время семантического анализа я столкнулся с проблемой повреждения данных.У меня есть вектор functionList, в котором хранится список функций, содержащий имя функции, тип, параметры и блок операторов.

Функция отслеживается в векторе functionList всякий раз, когда она впервые встречается в исходном коде:

virtual void Visit(AST::FunctionDeclare& p_node) override {
    if (ST->Insert(p_node.getName(), p_node.getType())) {
        p_node.getParams()->Accept(*this);
        p_node.getBlock()->Accept(*this);

        if (p_node.getType() != typeStack.top()) {
            Error("Function return type is incorrect!");
            return;
        } else {
            typeStack.pop();
        }

        // Keep track of this declared function to run it when called.
        AST::FunctionDeclare newNode = p_node;
        functionList->push_back(&newNode);
    } else {
        hasErrored = true;
    }
}

Действие «Поиск», приведенное ниже при проверке вызова функции, вызывает упомянутое искажение данных:

virtual void Visit(AST::FunctionCall& p_node) override {
    // Verify function exists
    if (ST->Lookup(p_node.getName()) == "") {
        std::string errorText = "No function with name '" + p_node.getName() + "' was found.";
        Error (errorText);
        return;
    }

    // Locate and setup required function
    AST::FunctionDeclare *pFunc = nullptr;
    // Find required function declaration
    for (auto tempFunc : *functionList) {
        if (tempFunc->getName() == p_node.getName()) // got it!
            pFunc = tempFunc;
    }

Действие «Поиск» выполняет следующее:

    // Returns type if found, empty if not
    std::string Lookup (std::string p_name) {
        for (int i = 0; i < _scopeVector.size(); i++) {
            if (_scopeVector[i]->find(p_name) == _scopeVector[i]->end()) {
                // No match yet
            } else {
                return _scopeVector[i]->find(p_name)->second; // return var type
            }
        }
        std::cerr << "Type name " << p_name << " not found in all of stack" << std::endl;
        return "";
    }

Появляетсякак будто я отслеживаю область памяти, которая теряется, когда я выполняю простое действие find ().Я не ожидал, что это действие изменит данные после того, как оно установлено, я не прав?Каков правильный подход в этом случае, чтобы избежать повреждения памяти?

1 Ответ

2 голосов
/ 19 мая 2019

Здесь вы храните указатель на локальную переменную:

AST::FunctionDeclare newNode = p_node;
functionList->push_back(&newNode);

Когда функция возвращается, &newNode недопустимо, поскольку newNode является локальной переменной.

Если ваша цель - поделиться указателями, используйте std::vector<std::shared_ptr<AST::FunctionDeclare>>.

...