简体   繁体   English

故意泄漏 std::vector 的 memory

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

I need to find a way to intentionally leak (take ownership of) the internal pointer of a std::vector so that its lifetime surpasses the one of the original container and so that it can be later deleted manually.我需要找到一种方法来故意泄漏(拥有) std::vector的内部指针,以便它的生命周期超过原始容器的生命周期,以便以后可以手动删除它。

Why?为什么? I'm working on a networked application using the C ENet library that needs to send large amounts of packets in a short amount of time.我正在使用 C ENet 库开发一个网络应用程序,该库需要在短时间内发送大量数据包。

I create network messages by writing the data to a std::vector<unsigned char> .我通过将数据写入std::vector<unsigned char>来创建网络消息。

Then in order to create a "packet," I use the enet_packet_create function, which takes a pointer to a byte array to be sent and its size.然后为了创建一个“数据包”,我使用了enet_packet_create function,它接受一个指向要发送的字节数组的指针及其大小。 In normal mode of operation, the function simply dynamically duplicates the given array on the heap, but there is also a "no allocate" option which only takes the pointer and size, leaving deleting to the creator using a callback function, and that's exactly what I'm trying to achieve -- the data is already there in the vector ready to be used, so there is no need to copy it again, as it could be costly.在正常操作模式下,function 只是在堆上动态复制给定数组,但还有一个“不分配”选项,它只接受指针和大小,使用回调 function 将删除留给创建者,这正是我正在努力实现 - 数据已经存在于可以使用的向量中,因此无需再次复制它,因为它可能很昂贵。

I need to find a way to intentionally leak the internal pointer of a std::vector我需要找到一种方法来故意泄漏std::vector的内部指针

Only way to leak the internal buffer of std::vector is to leak the vector itself.泄漏std::vector内部缓冲区的唯一方法是泄漏向量本身。 Example:例子:

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

But leaking memory is not a good idea in general.但是泄漏 memory 通常不是一个好主意。

I did not literally mean to create a memory leak, the memory needs to be freed.我并不是真的要创建 memory 泄漏,memory 需要被释放。

In this case, the only solution is to make sure that the lifetime of the std::vector is longer than the usage of the buffer.在这种情况下,唯一的解决方案是确保std::vector的生命周期长于缓冲区的使用时间。 A vector always releases the buffer it owns on destruction, and there is no way to extract ownership from it except into another vector.向量总是在销毁时释放它拥有的缓冲区,并且没有办法从中提取所有权,除非进入另一个向量。

One way to achieve that is this:实现这一目标的一种方法是:

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
}

Example adapted form this answer (now that this question has shifted from leaking to transferring ownership, this is close to a duplicate).示例改编自这个答案(现在这个问题已经从泄漏转移到转移所有权,这接近重复)。

You could use a pool allocator to avoid redundant allocations for each packet.您可以使用池分配器来避免每个数据包的冗余分配。

You don't need to leak anything.你不需要泄漏任何东西。 Just use the userData field of the ENetPacket structure to store the to-be-deleted std::vector , and just delete it in the callback:只需使用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