You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++接收RabbitMQ数据时触发SIGABRT错误求助

问题分析与解决方案

错误原因

触发SIGABRT的核心原因是类成员connection为空的boost::shared_ptr,调用其operator->时触发断言失败,根源在Receiver构造函数的变量拼写错误:

在Receiver::Receiver中,你声明了局部变量conncetion(拼写错误,多了一个'n'),但调用setConnection时传入的是未初始化的类成员connection(空指针),导致创建好的RabbitMQ Channel实例没有被赋值给类成员,后续调用connection->DeclareQueue时自然触发空指针断言。

修复步骤

1. 修正构造函数的变量拼写错误

修改receiver.cpp中的构造函数,将局部变量名改为正确的connection,确保创建的Channel实例被赋值给类成员:

Receiver::Receiver(std::string hostname, int port, std::string username, std::string password, std::string virtualHost) {
    // 修正局部变量拼写错误,将conncetion改为connection
    AmqpClient::Channel::ptr_t connection = AmqpClient::Channel::Create(
            hostname, port, username, password, virtualHost
        );
    this->setConnection(connection);
}

或者更简洁的写法,跳过局部变量直接赋值:

Receiver::Receiver(std::string hostname, int port, std::string username, std::string password, std::string virtualHost) {
    this->connection = AmqpClient::Channel::Create(
            hostname, port, username, password, virtualHost
        );
}

2. 移除main函数中多余的外层循环

revceiveRawCommand内部已经包含无限循环用于监听消息,main函数中的外层while(1)完全多余,修改main函数:

int main() {
    CommandInvoker *invoker = new CommandInvoker;
    CommandHandler *handler = new CommandHandler;
    Receiver *receiver = new Receiver;

    std::cout << "Waiting for command...\n";
    receiver->revceiveRawCommand("hello_queue");

    // 补充删除receiver,原代码遗漏了该内存释放
    delete invoker;
    delete handler;
    delete receiver;
    return 0;
}

3. 完善消息回调的调用

当前代码注释掉了commandCallback的调用,修复后需要传入invoker和handler,先修改revceiveRawCommand的参数:

void Receiver::revceiveRawCommand(std::string queue, CommandInvoker* invoker, CommandHandler* handler) {
    try {
        this->connection->DeclareQueue(queue, false, true, false, false);
        AmqpClient::Envelope::ptr_t envelope;

        std::string consumer_tag = connection->BasicConsume(queue, "", true, false, false);
        while(true) {
            connection->BasicConsumeMessage(envelope, consumer_tag, 0);

            if (envelope) {
                std::string message = envelope->Message()->Body();
                this->commandCallback(message, invoker, handler);
            }
        }

    } catch (const std::exception& e) {
        std::cerr << "Exception caught: " << e.what() << std::endl;
    }
}

再修改main中的调用:

receiver->revceiveRawCommand("hello_queue", invoker, handler);

4. 避免内存泄漏(可选但推荐)

改用std::unique_ptr管理动态分配的对象,无需手动调用delete:

int main() {
    auto invoker = std::make_unique<CommandInvoker>();
    auto handler = std::make_unique<CommandHandler>();
    auto receiver = std::make_unique<Receiver>();

    std::cout << "Waiting for command...\n";
    receiver->revceiveRawCommand("hello_queue", invoker.get(), handler.get());

    return 0;
}

验证修复

完成上述修改后,重新编译运行接收端,RabbitMQ Channel连接会被正确初始化,不再触发空指针断言,能够正常监听队列中的消息并执行回调逻辑。

内容的提问来源于stack exchange,提问作者biginner_sama

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 21:38:10