首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C++从push_back到静态向量的去分配

C++从push_back到静态向量的去分配
EN

Stack Overflow用户
提问于 2013-11-27 12:20:28
回答 2查看 932关注 0票数 0

在下面的代码中,我尝试实现一个缓存的单例模式(每个乘法(N)只存在一次)。

代码语言:javascript
复制
  vector<Multiplication>& Multiplication::cacheVector() {
    static vector<Multiplication> cache({Multiplication(0)});

    return cache;
  }

  const Multiplication& Multiplication::getInstance(unsigned int order) {

    while (order >= cacheVector().size()) {
      cacheVector().push_back(Multiplication(cacheVector().size()));      
    }

    return cacheVector()[order];      
  }

问题是:当我尝试使用缓存的乘法实例时,我会得到一个分段错误。瓦兰德告诉我,我调用无效的读取,因为数据在getInstance函数中是免费的:

代码语言:javascript
复制
==5471==    by 0x4C2054D: std::_Vector_base<tnp::Multiplication, std::allocator<tnp::Multiplication> >::_M_deallocate(tnp::Multiplication*, unsigned long) (stl_vector.h:174)
==5471==    by 0x4C2029D: _ZNSt6vectorIN3tnp14MultiplicationESaIS1_EE19_M_emplace_back_auxIJS1_EEEvDpOT_ (stl_vector.h:430)
==5471==    by 0x4C1FFDF: _ZNSt6vectorIN3tnp14MultiplicationESaIS1_EE12emplace_backIJS1_EEEvDpOT_ (vector.tcc:101)
==5471==    by 0x4C1EE9F: std::vector<tnp::Multiplication, std::allocator<tnp::Multiplication> >::push_back(tnp::Multiplication&&) (stl_vector.h:920)
==5471==    by 0x4C1DF52: tnp::Multiplication::getInstance(unsigned int) (multiplication.cpp:83)

乘法没有自己的复制构造函数,这些字段:

代码语言:javascript
复制
  class Multiplication { 

    const unsigned int order;
    const vector<Product> valueSum;
    const vector<Product> partialDerSum;
    const vector<Multiplication>& instances;

(在实例中,除了order==0之外,缓存向量的反向引用),取消分配可能发生在valueSum和partialDerSum向量上。

那么,为什么C++要对我的新乘法实例进行重新分配呢?它不应该把它复制到向量中吗?我想避免任何显式的堆分配,因为指针间接会在以后的路上造成一些性能上的损失。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-11-27 12:31:04

你还没有指出导致分段故障的确切线路,所以我只是粗略地猜测:

您可能在某个地方存储了对乘法实例的引用,然后在向量中添加了新项,从而导致向向量重新分配它的内部内存,因此您的引用点指向了已分配的内存

票数 2
EN

Stack Overflow用户

发布于 2013-11-27 12:36:01

对于它崩溃的原因,不是一个真正的答案,而是对这些问题的解释:

那么,为什么C++要对我的新乘法实例进行重新分配呢?它不应该把它复制到向量中吗?

事实上,它确实复制或移动。

让我们稍微描述一下这一行:

代码语言:javascript
复制
cacheVector().push_back(Multiplication(cacheVector().size()));  

Multiplication(cacheVector().size())被分配到某个地方,但是cacheVector的内存不在同一个位置,因此向量复制或移动(这里肯定是移动)从Multiplication中创建cacheVector实例时的数据。

可以帮助您理解这一点的下面是一个小例子

您可以看到对“普通”构造函数的调用,然后是对move构造函数的调用。然后,编译必须删除移动到向量的实例,因此它确实调用了与"normal“构造函数一起分配的实例上的析构函数。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20242359

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档