如何避免多余的数据缓冲区复制到字符串?

时间:2018-09-15 19:34:05

标签: c++

以下是用于将多个数据保存到myqueue的框架代码。每个数据块可能很大(例如几个MB或更多)。我有两个问题:

  • 通过从string创建buf *,是否涉及将buf复制到新位置?有性能方面的问题吗?

  • dequeue函数中,我返回string作为参考,这是避免创建新字符串的正确方法吗?

谢谢。

int main() {
   std::queue<std::string> myqueue;
   ... 
   // receive large number
   // data, and enqueue to myqueue
}

void enqueue()
{
   char* buf = (char*)malloc(count);
   myqueue.push(std::string(buf));
   free(buf);
}

std::string& dequeue()
{
   std::string& item = myqueue.front();
   myqueue.pop()
   return item;
}

2 个答案:

答案 0 :(得分:2)

  

通过从buf *创建字符串,是否涉及将buf复制到新位置?有性能方面的问题吗?

是的。它可能是。除非用法清楚,否则很难说是否需要关注。

  

在出队功能中,我返回字符串作为参考,这是避免创建新字符串的正确方法吗?

不,不是。当函数返回时,您将获得对未激活对象的引用。通过引用访问对象将导致未定义的行为。安全并按值返回对象。

std::string dequeue()
{
   std::string item = myqueue.front();
   myqueue.pop();
   return item;
}

答案 1 :(得分:2)

void enqueue()
{
   char* buf = (char*)malloc(count);
   myqueue.push(std::string(buf));
   free(buf);
}

std::string(buf)不能拥有buf的所有权,因此您将不得不分配更多的内存,将buf复制到该内存中,然后将其放入队列中。我们可以通过以std::string开始来做得更好。那会给你类似的东西

void enqueue()
{
   myqueue.emplace(count, '\0');
}

或者如果您需要将数据加载到字符串中

void enqueue()
{
    std::string buf(count, '\0');
    load_data(buf.data());
    myqueue.push(std::move(buf));
}

std::string& dequeue()
{
   std::string& item = std::move(myqueue.front());
   myqueue.pop();
   return item;
}

您正在返回对本地对象的引用。这将导致不确定的行为,因为一旦函数结束,本地字符串就会被销毁,并且留下悬挂的引用。为了防止这种情况,您只能按值返回字符串,例如

std::string dequeue()
{
   std::string item = myqueue.front();
   myqueue.pop();
   return item;
}