繁体   English   中英

故意泄漏 std::vector 的 memory

[英]Intentionally leak the memory of a std::vector

我需要找到一种方法来故意泄漏(拥有) std::vector的内部指针,以便它的生命周期超过原始容器的生命周期,以便以后可以手动删除它。

为什么? 我正在使用 C ENet 库开发一个网络应用程序,该库需要在短时间内发送大量数据包。

我通过将数据写入std::vector<unsigned char>来创建网络消息。

然后为了创建一个“数据包”,我使用了enet_packet_create function,它接受一个指向要发送的字节数组的指针及其大小。 在正常操作模式下,function 只是在堆上动态复制给定数组,但还有一个“不分配”选项,它只接受指针和大小,使用回调 function 将删除留给创建者,这正是我正在努力实现 - 数据已经存在于可以使用的向量中,因此无需再次复制它,因为它可能很昂贵。

我需要找到一种方法来故意泄漏std::vector的内部指针

泄漏std::vector内部缓冲区的唯一方法是泄漏向量本身。 例子:

std::vector<T>* ptr = new std::vector<T>;
ptr = nullptr; // memory leaked succesfully

但是泄漏 memory 通常不是一个好主意。

我并不是真的要创建 memory 泄漏,memory 需要被释放。

在这种情况下,唯一的解决方案是确保std::vector的生命周期长于缓冲区的使用时间。 向量总是在销毁时释放它拥有的缓冲区,并且没有办法从中提取所有权,除非进入另一个向量。

实现这一目标的一种方法是:

std::unordered_map<unsigned char*, std::vector<unsigned char>> storage;
void foo()
{
    std::vector<unsigned char> vec;
    // fill vec here
    unsigned char* ptr = vec.data();
    storage[ptr] = std::move(vec);
    auto destroy_callback = [](unsigned char* ptr) {
        storage.erase(ptr);
    }
    // pass ptr and destroy_callback into some async API
}

示例改编自这个答案(现在这个问题已经从泄漏转移到转移所有权,这接近重复)。

您可以使用池分配器来避免每个数据包的冗余分配。

你不需要泄漏任何东西。 只需使用ENetPacket结构的userData字段来存储要删除的std::vector ,并在回调中将其删除即可:

void myCallback(ENetPacket *pkt) {
    std::vector<uint8_t> *data=(std::vector<uint8_t> *)pkt->userData;
    delete data;
}

void sendData() {
    std::vector<uint8_t> *data=new std::vector<uint8_t>;
    //Fill data here
    ENetPacket *pkt=enet_packet_create(data.data(), data.size(), ENET_PACKET_FLAG_NO_ALLOCATE);
    pkt->userData=(void*)data;
    pkt->freeCallback=myCallback;

}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM