【问题标题】:How do I "reset" a buffer?如何“重置”缓冲区?
【发布时间】:2013-02-12 21:12:48
【问题描述】:

假设我创建了一个成员变量指针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
}

【问题讨论】:

  • 如果它只是一个缓冲区指针,“释放所有不必要的内存”大约是删除它的 100%。通常,开发人员不会释放内存,只是回收缓冲区并用新数据覆盖它,(参见@andre)。
  • 等等,你想释放而不是删除它?这完全没有意义!
  • ..或者,换句话说,请参阅@MooingDuck 评论。
  • 好吧,因为我不知道缓冲区会放入多少数据,所以第一次可以占用1,000,000字节,第二次只能占用1个字节。我想以某种方式释放 1,000,000 个字节并“从头开始”,这样如果我只需要 1 个字节,我就不会第二次分配所有 100 万个字节。
  • 不值得。使用大小合理的缓冲区池,并在运行期间放弃 new、delete、realloc 等任何操作。如果您的服务器(或其他)经常需要处理具有广泛变化的有效负载的不同协议,请使用每个缓冲区大小不同的缓冲区 poo 数组(128、1K、4K、16K 等)。始终以 128 开头。如果“whatever”返回 128 字节,则使用下一个大小,如果缓冲区返回未填充,则使用下一个大小,(或再次以 128 开头)。

标签: c++ pointers memory buffer


【解决方案1】:

如果您知道缓冲区中的内容数量与缓冲区中的剩余空间,请尝试realloc()

【讨论】:

    【解决方案2】:

    只使用一个原始指针,不;但是如果你保留一个大小变量,你可以相对容易地重置缓冲区。

    然而,这被标记为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);
        }
    };
    

    【讨论】:

    • 第一句话具有误导性,因为它可以很容易地用原始指针来完成。一个指向数据开头的指针,一个指向数据结尾的指针,一个指向缓冲区结尾的指针。
    【解决方案3】:

    缓冲区通常需要最大大小和当前大小。要“重置”,您可以将当前大小设置为零。当您再次使用它时,您可能需要增大或缩小缓冲区的最大大小。使用reallocmalloc/newmemcpy(realloc 在增长时在内部执行)将现有数据移动到新缓冲区。

    请注意,这些都是昂贵的操作。如果您希望缓冲区从使用到使用需要增长,您可以考虑每次将其最大大小加倍。这有效地摊销了分配和复制的成本。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-07-11
      • 1970-01-01
      相关资源
      最近更新 更多