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开始)。第一句话具有误导性,因为它很容易用原始指针完成。指向数据开头的指针、指向数据结尾的指针和指向缓冲区结尾的指针。