C ++在不激活构造函数的情况下分配内存

时间:2011-01-01 23:31:57

标签: c++ memory-management

我正在读取一个文件中的值,我将在读取它时将其存储在内存中。我在这里读到,在C ++中处理内存位置的正确方法是始终使用new / delete,但是如果我这样做:

DataType* foo = new DataType[sizeof(DataType) * numDataTypes];

然后,这将为每个创建的实例调用默认构造函数,我不希望这样。我打算这样做:

DataType* foo;
char* tempBuffer=new char[sizeof(DataType) * numDataTypes];
foo=(DataType*) tempBuffer;

但是我认为这会是某种类型 - 不安全感的poo-poo。那我该怎么办?

现在我正在研究这个问题,我发现有些人说阵列很糟糕,矢量很好。我试图更多地使用数组因为我认为我是一个坏男孩通过填充我的程序(我认为是)较慢的向量。我该怎么用?

7 个答案:

答案 0 :(得分:7)

使用矢量!!!由于您知道元素的数量,因此请确保先保留内存(通过在插入元素之前调用myVector.reserve(numObjects)。)。

通过这样做,您不会调用类的默认构造函数。

所以使用

std::vector<DataType> myVector; // does not reserve anything
...
myVector.reserve(numObjects); // tells vector to reserve memory

答案 1 :(得分:5)

您可以使用::operator new分配任意大小的内存块。

DataType* foo = static_cast<DataType*>(::operator new(sizeof(DataType) * numDataTypes));

这里使用::operator new优于malloc的主要优点是它会失败并会与任何new_handlers等集成。您需要使用::operator delete <清理内存/ p>

::operator delete(foo);

常规new Something当然会调用构造函数,毕竟这是new的重点。

避免额外构造(例如默认构造函数)或者出于性能原因推迟它们是一回事,完全跳过任何构造函数是另一回事。我得到的印象是你有像

这样的代码
DataType dt;
read(fd, &dt, sizeof(dt));

如果你这样做,你已经把窗户的安全性抛到了窗外。

为什么要通过不调用构造函数来完成?

答案 2 :(得分:2)

您可以使用new char[]分配内存,为数组中的每个元素调用所需的构造函数,然后一切都是类型安全的。阅读What are uses of the C++ construct "placement new"?

这就是std::vector在其下工作的方式,因为它为效率分配了一些额外的内存,但是在实际需要之前不会在额外的内存中构造任何对象。

答案 3 :(得分:1)

你应该使用矢量。它允许您逐个构建其内容(通过push_back或类似内容),这听起来就像您想要做的那样。

答案 4 :(得分:1)

vector<DataType> dataTypeVec(numDataTypes);

正如你所知,你的第一行包含一个错误(不需要乘以sizeof)。

答案 5 :(得分:1)

我认为你不应该关心使用向量的效率,如果你不在任何地方插入新元素,而是在向量的末尾(因为向量的元素存储在一个连续的内存块中)。

答案 6 :(得分:1)

在其他人所说的基础上,如果你运行这个程序,同时在整数的文本文件中进行管道,这将填充下面类的数据字段,如:

./allocate < ints.txt

然后你可以这样做:

#include <vector>
#include <iostream>

using namespace std;

class MyDataType {
public:
  int dataField;
};


int main() {

  const int TO_RESERVE = 10;

  vector<MyDataType> everything;
  everything.reserve( TO_RESERVE );

  MyDataType temp;
  while( cin >> temp.dataField ) {
    everything.push_back( temp );
  }

  for( unsigned i = 0; i < everything.size(); i++ ) {
    cout << everything[i].dataField;
    if( i < everything.size() - 1 ) {
      cout << ", ";
    }
  }
}

对于我来说,对于我有4个整数的列表,给出:

5, 6, 2, 6