C++ “我该怎么做?”;重置";缓冲区?
假设我创建一个成员变量指针C++ “我该怎么做?”;重置";缓冲区?,c++,pointers,memory,buffer,C++,Pointers,Memory,Buffer,假设我创建一个成员变量指针pBuffer。我将这个缓冲区发送到某个未知的区域,以填充数据。现在假设pBuffer中有任意数量的数据 问:有没有一种方法可以在不完全删除pBuffer的情况下重置它,同时释放它占用的所有不必要的内存 例如: class Blah { public: unsigned char* pBuffer; Blah(){pBuffer = NULL;} ~Blah(){} FillBuffer() { //fill
pBuffer
。我将这个缓冲区发送到某个未知的区域,以填充数据。现在假设pBuffer中有任意数量的数据
问:有没有一种方法可以在不完全删除pBuffer的情况下重置它,同时释放它占用的所有不必要的内存
例如:
class Blah
{
public:
unsigned char* pBuffer;
Blah(){pBuffer = NULL;}
~Blah(){}
FillBuffer()
{
//fill the buffer with data, doesn't matter how
}
ResetBuffer()
{
//????? reset the buffer without deleting it, still deallocate memory ?????
}
};
int main()
{
Blah b;
b.FillBuffer();
b.ResetBuffer();
b.FillBuffer(); //if pBuffer were deleted, this wouldn't work
}
如果您知道缓冲区中的内容量与缓冲区中的剩余空间之比,请尝试
realloc()
。仅使用单个原始指针,否;但是,如果保留大小变量,则可以相对轻松地重置缓冲区
但是,由于这被标记为C++
,我想提醒您不要这样做,而是提出一个替代方案。这满足了您的要求,即允许分配内存,然后稍后“重置”缓冲区,而无需释放内存。另一个好处是,使用std::vector
意味着您不必担心后续调用FillBuffer()
时内存泄漏,特别是当现有缓冲区太小且需要重新分配时
#include <vector>
class Blah
{
public:
std::vector<unsigned char> pBuffer;
Blah(){}
~Blah(){}
FillBuffer()
{
//fill the buffer with data, doesn't matter how
}
ResetBuffer()
{
pBuffer.clear();
// if you _really_ want the memory "pointed to" to be freed to the heap
// use the std::vector<> swap idiom:
// std::vector<unsigned char> empty_vec;
// pBuffer.swap(empty_vec);
}
};
#包括
课堂废话
{
公众:
std::载体pBuffer;
布拉(){}
~Blah(){}
FillBuffer()
{
//用数据填充缓冲区,不管怎样
}
ResetBuffer()
{
pBuffer.clear();
//如果您真的希望将“指向”的内存释放到堆中
//使用std::vector swap习惯用法:
//std::vector empty_vec;
//pBuffer.swap(空向量);
}
};
缓冲区通常需要最大大小和当前大小。要“重置”,请将当前大小设置为零。再次使用时,可能需要增大或缩小缓冲区的最大大小。使用realloc
或malloc
/new
和memcpy
(realloc在增长时内部执行)将现有数据移动到新缓冲区
请注意,这些都是昂贵的操作。如果您希望缓冲区需要从使用到使用,您可能会考虑每次增加最大的大小。这有效地分摊了分配和复制的成本。如果它只是一个缓冲区指针,“释放所有不必要的内存”大约是删除它的100%。通常,开发人员不会释放内存,只是回收缓冲区并用新数据覆盖它(请参见@andre)。等等,你想释放内存,但不想删除它吗?那完全没有道理!。。或者,换一种说法,请参阅@MooingDuck comment。由于我不知道将有多少数据放入缓冲区,第一次它可能会占用1000000字节,第二次它只能占用1字节。我想取消分配1000000字节,并以某种方式“从头开始”,这样,如果我只需要1个字节,就不会在第二次分配所有100万字节。这不值得。使用一个大小合理的缓冲池,在跑步过程中放弃new、delete、realloc等功能。如果您的服务器(或其他任何服务器)经常需要处理不同的协议和各种不同的有效负载,请使用一组缓冲区poo,每个poo中有不同大小的缓冲区(128、1K、4K、16K等)。总是从128开始。如果“whatever”返回128字节,则使用上一个大小;如果缓冲区返回未填充,则使用下一个大小(或再次从128开始)。第一句话具有误导性,因为它很容易用原始指针完成。指向数据开头的指针、指向数据结尾的指针和指向缓冲区结尾的指针。