当前位置: 首页 > 知识库问答 >
问题:

使用std::vector时,简单增强UDP接收器gest堆释放后使用

漆雕宏浚
2023-03-14

我很难理解为什么我非常简单的UDP接收器会出现使用后无堆错误(由ASAN诊断)。其思想是侦听传入数据包的可配置数量的本地端口。

我在这里发布了一个简化版的课程

UdPreceVer.hpp

class UdpReceiver
{
  public:
    UdpReceiver(std::vector<int> listen_ports);
    void run();
  protected:
    boost::asio::io_service m_io;
    char m_receive_buffer[MAX_RECEIVE_LENGTH];
    std::vector<udp::endpoint> m_endpoints;
    std::vector<udp::socket> m_sockets;
    void handleUdpData(const boost::system::error_code& error, size_t bytes_recvd, int idx);

}; 

UdPreceVer.cpp

UdpReceiver::UdpReceiver(std::vector<int> listen_ports) : 
  m_io()
{ 
  
  int idx = 0;
  try {
  for (auto port: listen_ports) {
    m_endpoints.push_back(udp::endpoint(udp::v4(), port));
    m_sockets.push_back(udp::socket(m_io, m_endpoints[idx]));
    m_sockets[idx].async_receive_from(
      boost::asio::buffer(m_receive_buffer, MAX_RECEIVE_LENGTH), m_endpoints[idx],
      boost::bind(&MessageParser::handleUdpData, this,
      boost::asio::placeholders::error,
      boost::asio::placeholders::bytes_transferred,
      idx)
    );
    idx++;
  }
  } catch(const std::exception &exc) 
  {
    std::cerr <<exc.what();
    exit(-1);
  }
}

根据ASAN,m_endpoints.push_back(udp::endpoint(udp::v4(),port))分配了一些动态内存,稍后的迭代会再次释放这些内存。这最终给了我免费后的使用,这会以一种不可预测的方式把我的应用程序搞乱。

我真的不明白在这种情况下使用std::vector怎么会不起作用。有什么想法吗?

共有1个答案

郏志诚
2023-03-14

async_receive_from的文档说明:“sender_endpoint对象的所有权由调用方保留,调用方必须保证在调用处理程序之前该对象是有效的。”

您的push_back可能会重新分配基础存储,从而使async_receive_from保留一个悬空引用。

要避免重新分配,请在进入循环之前为必要数量的元素保留空间:

m_endpoints.reserve(listen_ports.size());
m_sockets.reserve(listen_ports.size());
 类似资料:
  • 问题内容: 背景: 我希望能够在我的iOS应用程序和服务器之间发送和接收UDP数据包。服务器将所有传入消息回显给应用程序客户端。 服务器已测试并确认可以正常工作 。我有一个StartViewController,它启动了两个实现GCDAsyncUdpSocketDelegate的类,一个用于发送,一个用于接收。“发送套接字”正在工作,服务器接收到消息。 问题: 在发送后,该应用程序再也不会取回传入

  • 这里是正确的代码,只更改为pre=null,cur=second。顺便说一下,在下一次迭代中pre=second和cur将变为second->next,这与上面给出的运行时解决方案相同。

  • 预备条件: Off-By-One 漏洞(基于栈) VM 配置:Fedora 20(x86) 继续使用已经被释放的堆内存指针叫做释放后使用。这个漏洞会导致任意代码执行。 漏洞代码: 编译命令: $gcc -o vuln vuln.c $sudo chown root vuln $sudo chgrp root vuln $sudo chmod +s vuln 注意:不像上一篇文章,ASLR 在这里是

  • 我有一个Springboot应用程序,Mule作为微服务在docker容器中运行。即使空闲时也需要大约700MB。注意到JVM分配了380 MB的堆,这是使用参数提供的最大堆。虽然分配了最大堆,但微服务在空闲时只使用大约50 MB。问题是如何从JVM释放未使用的内存。 似乎减少MaxHeapFreeRatio我们可以要求JVM在有更多可用内存时收缩。然而没有太大区别,JVM也没有释放内存。但是当我

  • 我在std::sort中发现了一个bug,特别是在一些QuickSort的实现中,我不知道问题是否出在一般的算法中。 精华: 当元素小于16时,所有的规范都被替换,因为std::sort使用插入排序。 当有17个或更多的元素时,使用快速排序,并从元素数量的对数限制递归深度,但向量在第一次__introsort_loop迭代时有时间恶化。 当有许多相同的元素时,就会出现向量损坏。用无效迭代器替换有效

  • 它在我的Xcode中运行正常,所以有人能告诉我有什么问题吗? 我测试了,问题是在为堆栈重新分配空间,但我不明白这个错误…测试用例是[1,null,2,3],所以1是根,2是1的右子,3是2的左子。解决方案应该返回数组[1,2,3]。