您的当前位置:首页正文

【问题记录】裸指针和智能指针

2024-11-30 来源:个人技术集锦

问题描述

今天写项目时(在与elastisearch服务端的交互模块),遇到一个裸指针和智能指针指向同一块空间,导致段错误Segmentation fault,特此记录。

//error code
#include "es.hh"

int main()
{
    // 创建es客户端,与es建立连接
    try
    {
        elasticlient::Client* client = new elasticlient::Client({"http://localhost:9200/"});

        // 创建索引
        EsIndex es_index(client, "user", "_doc");
        es_index.append("nickname", "text", "ik_maxword", true);
        es_index.append("user_id", "keyword", "standard");
        es_index.append("phone", "keyword", "standard");
        es_index.append("description", "text", "standard", false);
        es_index.append("avatar_id", "keyword", "standard", false);

        es_index.create();

        // 插入文档数据
        EsUpdate ud1(client, "user", "_doc", 1);
        ud1.addProperty("user_id", "USER4b862aaa-2df8654a-7eb4bb65-11111111");
        ud1.addProperty("nickname", "昵称 1");
        ud1.addProperty("phone", "手机号 1");
        ud1.addProperty("description", "签名 1");
        ud1.addProperty("avatar_id", "头像 1");

        ud1.submit();
        
        EsUpdate ud2(client, "user", "_doc", 2);
        ud2.addProperty("user_id", "USER14eeeaa5-442771b9-0262e455-e4663d1d");
        ud2.addProperty("nickname", "昵称 2");
        ud2.addProperty("phone", "手机号 2");
        ud2.addProperty("description", "签名 2");
        ud2.addProperty("avatar_id", "头像 2");

        ud2.submit();
    }
    catch (std::exception &e)
    {
        std::cout << e.what() << std::endl;
    }

    
    return 0;
}

其中,EsIndexEsUpdate对象都以智能指针shared_ptr保存一份es客户端的副本,用于与es服务端交互。

class EsIndex
{
public:
	//....
private:
    std::shared_ptr<elasticlient::Client> _client;
    //...
};

class EsUpdate
{
public:
	//....
private:
    std::shared_ptr<elasticlient::Client> _client;
    //...
};

刚开始以裸指针传入EsIndexEsUpdate,用于其内部创建智能指针。程序运行后报段错误,使用gdb调试后,提示异常信息如下:

错误原因

改正

不要混用裸指针和智能指针来指向同一块内存。 如果你决定使用智能指针来管理内存,就应完全依赖它,而避免在代码中保留指向同一内存的裸指针。

#include "es.hh"

int main()
{
    // 创建es客户端,与es建立连接
    try
    {
        // elasticlient::Client* client = new elasticlient::Client({"http://localhost:9200/"});
        auto client = std::make_shared<elasticlient::Client>(std::initializer_list<std::string>{"http://localhost:9200/"});
        // 创建索引
        EsIndex es_index(client, "user", "_doc");
        es_index.append("nickname", "text", "ik_maxword", true);
        es_index.append("user_id", "keyword", "standard");
        es_index.append("phone", "keyword", "standard");
        es_index.append("description", "text", "standard", false);
        es_index.append("avatar_id", "keyword", "standard", false);

        es_index.create();

        // 插入文档数据
        EsUpdate ud1(client, "user", "_doc", 1);
        ud1.addProperty("user_id", "USER4b862aaa-2df8654a-7eb4bb65-11111111");
        ud1.addProperty("nickname", "昵称 1");
        ud1.addProperty("phone", "手机号 1");
        ud1.addProperty("description", "签名 1");
        ud1.addProperty("avatar_id", "头像 1");

        ud1.submit();
        
        EsUpdate ud2(client, "user", "_doc", 2);
        ud2.addProperty("user_id", "USER14eeeaa5-442771b9-0262e455-e4663d1d");
        ud2.addProperty("nickname", "昵称 2");
        ud2.addProperty("phone", "手机号 2");
        ud2.addProperty("description", "签名 2");
        ud2.addProperty("avatar_id", "头像 2");

        ud2.submit();

        // 搜索内容
        // std::string search_body = R"({
        // "query": {
        //     "match_all": {}
        //     }
        // })";
        // cpr::Response response = client.search("user", "_doc", search_body);

        // std::cout << "状态码: " << response.status_code << std::endl;
        // std::cout << "查找内容:" << response.text << std::endl;
    }
    catch (std::exception &e)
    {
        std::cout << e.what() << std::endl;
    }

    
    return 0;
}
显示全文