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
相关产品推荐
相关产品推荐

