使用动态对象分配std矢量内容

时间:2015-05-21 09:21:26

标签: c++ malloc std stdvector

我有一个 std::vector< MyObject* > my_vector; 哪个不是空的,我想分配并推送一定数量的MyObject *。 我知道要推送的对象数量。有没有比这更好的方法(优化/更快):

int object_count = 10000;
for(int index = 0; index < object_count; index++)
{
    my_vector.push_back(new MyObject());
}

就像在一次调用malloc中为所有MyObject分配一样,然后将结果memcpy给my_vector。 有什么想法吗?

更新 我的问题是召唤新的10000次。我希望能够分配一大块内存并将内存交换到my_vector的末尾。

2 个答案:

答案 0 :(得分:3)

你可以在向量中保留足够的空间,因此它只会分配一次内存。使用std :: unique_ptr&lt;&gt;:

也是一种好习惯
std::vector<std::unqiue_ptr<MyObject> > my_vector;
int object_count = 10000;
my_vector.reserve(object_count);
for(int index = 0; index < object_count; index++)
{
  my_vector.push_back(std::unique_ptr<MyObject>(new MyObject()));
}

更新:如果您无法使用(或者不想)使用unique_ptr,只需在代码中添加reserve以预分配内存。

更新2 :据我所知,您希望避免new MyObject()中的内存分配。一个可行的解决方案是以下(不适用于实际应用):

// a very simple example
class Pool {
public:
  Pool() : array(new MySpecObjects[10000]), counter(10000); {}
  MySpecObject* get() {
    --counter;
    return array[counter];
  }
  void reset() {
    counter = 10000;
  }
  MySpecObject* array;
  size_t counter;
};

static Pool* getPool() {
  static Pool pool;
  return pool;
}

std::vector<MyObject* > my_vector;
int object_count = 10000;
my_vector.reserve(object_count);
for(int index = 0; index < object_count; index++) {
  my_vector.push_back(getPool().get()));
}

这是一个简化的例子,它不是线程安全的,Pool会在程序关闭时清除它的内存。它背后的想法类似于flyweight gof patternsee boost for example

更新3 :也许更好的解决方案是在这里使用intrusive lists。然后,您需要做的就是预先分配对象的向量:

class MyObject : public boost::intrusive::list_base_hook<> {
  ...
};
// MySpecObject1 and MySpecObject2 inherit MyObject
std::vector<MySpecObject1> objs1(10000);
std::vector<MySpecObject2> objs2(10000);
...

typedef boost::intrusive::list<MyObject> BaseList;

BaseList list;
for (MyObject& ref : objs1) {
  list.push_back(ref);
}
for (MyObject& ref : objs2) {
  list.push_back(ref);
}

请注意,BaseList不拥有自己的节点。当你对它执行push_back时,list只是将一个对象链接到现有列表,不执行任何分配。

答案 1 :(得分:1)

标准功能std::generate_n似乎符合您的需求:

// Reserve space in vector to prevent unneeded reallocations
my_vector.reserve(my_vector.capacity() + 10000);
// Use back inserter to automatically call push_back each time 
// generate_n assigns value. Lambda will be called at each iteration
// constructing new object.
std::generate_n(std::back_inserter(my_vector), 10000, 
            []() { return new MyObject; });