• 记录一个奇怪的问题:代码中只要访问某对象的成员就会发生段错误,程序立即异常退出。


    11月13日晚

    问题情景

    问题发生在编写rpc项目的时候,项目已经编写完成。在测试的时候发现了这个问题。问题代码如下:

    // 创建 MprpcController 对象
    MprpcController *controller = new MprpcController();
    
    // 发起rpc方法调用
    stub.Login(controller, &request, &response, nullptr);
    
    if (controller->Failed())
    {
    	// 处理相应逻辑
    }
    else
    {
    	// 处理相应逻辑
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    问题出现在上面代码的第7行,只要访问controller的成员就发生段错误(这一点可以确定)。按道理来说这里不应该出现段错误,因为段错误一般是数组越界、访问了空指针或是访问了已经释放的内存。但是我使用gdb调试打印这里controller的值,并不是nullptr,那就只有可能是访问了已经释放的内存,又由于controller的值并不为nullptr,应该是原来存放controller指向对象的内存又放了别的东西。但是我不知道为什么会发生这样的情况,我觉得按照逻辑来说这是不可能的,原因如下:

    • 从创建controller起到第七行代码,中间只调用了一个成员函数,controller作为该函数的参数被传了进去,但是传进去的是指针,Login函数内部的形参指针,是controller的拷贝,即使在Login函数的作用域中销毁了该形参,仍然影响不到controller所指向的对象。

    所以我不理解这里为什么会发生段错误。gdb调式时有个奇怪的现象,我尝试使用p controller->m_failed打印controller的成员对象,输出结果告诉我他没有名为m_failed的成员对象。这一切似乎都在证实上面的猜测。但是我不知道controller所指对象究竟是怎么被释放的。

    错误解决办法

    解决方法很简单,既然可能的错误原因是访问了已被释放的内存,那么我就让controller所指对象根本不可能被释放。就是使用new申请一片堆内存,最后用deletecontroller释放掉,只需做两行修改。代码如下:

    // 创建 MprpcController 对象
    MprpcController *controller = new MprpcController();
    
    // 发起rpc方法调用
    stub.Login(controller, &request, &response, nullptr);
    
    if (controller->Failed())
    {
        std::cout << controller->ErrorText() << std::endl;
        LOG_ERR("%s", controller->ErrorText().c_str());
    }
    else
    {
        if (0 != response.result().errcode())
            std::cout << "Rpc login response error: " << response.result().errmsg() << std::endl;
        
        std::cout << "Rpc login success: " << response.success() << std::endl;
    }
    delete controller;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    求路过的大佬解答一下我的问题

    11月14日上午

    我想明白了

    昨天晚上脑子抽抽儿了,我忽视了一个基础而又关键的问题。

    MprpcController *controller;
    
    • 1

    像这样的语句只能声明一个指针,内存里不论是堆还是栈都没有实际的MprpcController对象。还需要手动去创建一个对象,然后让controller指向它。

    这么简单的错误以后别再犯了🙏🙏🙏🙏🙏🙏🙏

  • 相关阅读:
    跟我学时序分析之基础时序参数
    Qt中实现页面切换的两种方式
    【读书笔记】【Effective C++】定制 new 和 delete、杂项讨论
    用Python实现广度优先搜索
    SpectralDiff论文阅读笔记
    java每日一记 —— 浅浅的说下在Lombok中遇到的一个坑
    文心一言 4.0 ERNIE-Bot 4.0 :ERNIE-Bot 4.0 大模型深度测试体验报告
    volatile 关键字(修饰符 volatile 告诉编译器,变量的值可能以程序未明确指定的方式被改变)
    GDB调试常用命令
    Sklearn 聚类算法的性能评估
  • 原文地址:https://blog.csdn.net/m0_51551385/article/details/127838618