[英]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.