Ошибка сегментации после возврата unique_ptr внутри пары из функции - PullRequest
2 голосов
/ 28 марта 2020

У меня есть фабрика, которая создает экземпляры классов из строк. KeyValueType - это абстрактный класс, который будет передан в функции Map / Reduce.

class KeyValueType {
public:
    virtual void parse(const std::string &) = 0;

    virtual std::string to_string() const = 0;
};

Фабрики в коде получают из общей библиотеки (чтобы иметь возможность конфигурировать сопоставление / сокращение функций с удаленного компьютера).

std::unique_ptr<KeyValueType> KeyValueTypeFactory::create() override {
    return std::make_unique<KeyValueType<T>>();
};
std::unique_ptr<KeyValueType> KeyValueTypeFactory::create(const std::string &str) override {
    std::unique_ptr<KeyValueType> ptr = this->create();
    ptr->parse(str);
    return ptr;
};

Итак, у меня есть следующий код, где я создаю два объекта ключ / значение и возвращаю их в виде пары unique_ptr

std::pair<std::unique_ptr<KeyValueType>, std::unique_ptr<KeyValueType>> 
get_key_value_from_json(const std::string &data, std::unique_ptr<KeyValueTypeFactory> &key_factory, std::unique_ptr<KeyValueTypeFactory> &value_factory) {
    boost::property_tree::ptree pt{};
    boost::property_tree::json_parser::read_json(dynamic_cast<std::stringstream &>(std::stringstream{} << data), pt);
    return { std::move(key_factory->create(pt.get("key", ""))),
             std::move(value_factory->create(pt.get("value", ""))) };
}
std::pair<std::unique_ptr<KeyValueType>, std::unique_ptr<KeyValueType>> blocking_get_result() {
        ... // Get json and config
        auto[key, value] = get_key_value_from_json(json, cfg->key_out_factory, cfg->value_res_factory);
        std::cout << "The result of Map/Reduce is " << value->to_string() << std::endl;
        return { std::move(key), std::move(value) };
}
int main() {
    auto[key, value] = blocking_get_result();
    std::cout << (value.get() == nullptr) << std::endl;
    std::cout << "The result of Map/Reduce is " << value->to_string() << std::endl;
    return 0;
}

Фактическая проблема заключается в том, что в blocking_get_result() функциональная клавиша и значение действительны, а виртуальная функция to_string() работает правильно, но после возврата пары из функции в основную unique_ptr не равна нулю, но to_string выдает ошибку сегментации. Кроме того, dynamic_cast для производного класса вызывает Segfault.

1 Ответ

1 голос
/ 28 марта 2020

Фактическая проблема заключалась в том, что получение конфигурации выполнялось с использованием dlopen и dlsym и перенос результата в shared_ptr. Таким образом, разделяемая библиотека была освобождена в blocking_get_result. Так в главном указатель в vtable стал недействительным.

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