【问题标题】:What exactly happens when I do buffer1.push_back(buffer2.front()) in C++?当我在 C++ 中执行 buffer1.push_back(buffer2.front()) 时究竟会发生什么?
【发布时间】:2016-01-20 15:55:10
【问题描述】:

帮助我理解这一点。 这是上下文。

  • 我正在用 C++ 编写程序。
  • 我有 2 个缓冲区(双端队列)。我们称它们为 buffer1 和 buffer2;
  • 我有 2 个线程:一个线程正在用随机值填充缓冲区 1。另一种是将最旧的buffer1值复制到buffer2;
  • 我正在使用互斥锁。

我想将 buffer1 的第一个位置内的值复制到 buffer2 中,为了执行此操作,我编写了以下代码行:

线程 1

   double a = 20.1;
   buffer1.push_back(a);

线程 2

buffer2.push_back(buffer1.front());

我的问题是: 执行此操作,我是在复制值还是通过引用传递值? 我解释我的问题。我在运行程序时遇到随机内存问题。我想确定问题的根源是否在这里。

谢谢大家。

【问题讨论】:

  • 你的容器里有什么?理想情况下,您应该提供minimal reproducible example
  • frontpush_back 的文档是否不清楚会发生什么?
  • @StoryTeller,你是对的。这是这里犯的错误,但不是在程序中。谢谢!我编辑了帖子。
  • @5gon12eder,容器有双打。
  • @NathanOliver,也许我在解释文档时遇到了问题(翻译问题):p 这对我来说不是很清楚。我不明白我是在复制(push_back)front() 给出的引用,还是复制front() 引用给出的值。

标签: c++ deque push-back double-free invalid-pointer


【解决方案1】:

首先让我们看一下您正在调用的函数。 std::deque::push_back 函数通过引用获取它的参数,所以不能在那里复制。而std::deque::front 返回一个reference(或const_reference),所以也不能在那里复制。

现在让我们看看底层容器,它默认为std::vector,它的push_backfront 函数与std::deque 相同。

但是,如果您仔细查看 std::vector::push_back 引用,您会发现对于第一次重载,数据需要为 CopyInsertable,因为这实际上是通过 复制初始化向量内的元素的方式/em> 你“推回”的对象(或者如果你的编译器和数据类型支持,移动)。

所以最后,如果你有一个复杂的类,你应该关注the rules of three, five or zero,如果是这样,那么你应该没问题,无论如何都不会有内存问题。如果您确实遵循三、五或零的规则,但仍然有问题,那么问题可能出在其他地方。尝试使用内存调试器,例如Valgrind 或类似的。如果您有一个多线程应用程序,您需要保护可以被多个线程同时修改的资源(使用例如互斥锁或信号量)。

【讨论】:

    【解决方案2】:

    根据thisstd::deque::front 返回对第一个元素的引用:

    deque::front:

    返回对双端队列容器中第一个元素的引用。

    并根据this deque::push_back 复制(或移动)给定元素的内容:

    deque::push_back:

    在双端队列容器的末尾添加一个新元素 当前最后一个元素。 val 的内容被复制(或移动)到 新元素。

    【讨论】:

      【解决方案3】:

      我会说您的问题出在其他地方。由于您在不同的线程中有 sn-ps,它们的顺序可能没有定义。你可以以这个序列结束:

      double a = 20.1;
      buffer1.push_back(a);
      buffer2.push_back(buffer1.front());
      

      在这种情况下一切正常,或者按照以下顺序:

      buffer2.push_back(buffer1.front());
      double a = 20.1;
      buffer1.push_back(a);
      

      在这种情况下,您在空容器上调用buffer1.front()。复制构造函数被一些随机数据调用并产生内存问题。

      【讨论】:

        猜你喜欢
        • 2023-04-01
        • 1970-01-01
        • 2023-03-29
        • 1970-01-01
        • 2015-10-23
        • 2013-06-13
        • 1970-01-01
        • 2019-07-29
        • 2012-06-06
        相关资源
        最近更新 更多