分配内存而不在C++中初始化它

Mis*_*ded 3 c++ memory new-operator

我熟悉C++,而且我遇到了内存管理问题.在C中,每当我想为任意数量的元素保留内存时,无论何种类型,我都会调用malloc()然后手动初始化(通过循环),以我想要的任何值.使用C++ new,一切都是自动初始化的.

问题是,我有一个BattlePoint类,它有点像这样:

class BattlePoint {
public:
    BattlePoint(int x, int y) : x(x), y(y) { };
    bool operator==(const BattlePoint &right);
    virtual ~BattlePoint();

private:
    int x, y;
};
Run Code Online (Sandbox Code Playgroud)

如您所见,它通过初始化程序获取一些x和y值,然后从中设置自己的x和y.问题是,这个函数将从一个函数中调用,该函数将分配它们的数组:

BattleShip::BattleShip(BattlePoint start, enum shipTypeSize size, enum shipOrientation orientation) : size(size), orientation(orientation) {
    points = new BattlePoint[size]; // Here be doubts.
}
Run Code Online (Sandbox Code Playgroud)

所以,我需要我的BattleShip的观点来保持一个BattlePoints数组,每个BattlePoints具有不同的初始值(例如0,1; 0,2; 0,3等).

问题是:我如何分配未初始化的内存?

朱利安

PS:我没有对工作方式做过任何测试new,我简单阅读维基百科关于它的文章说:

在C++编程语言中,以及在许多基于C++的语言中,new是一种语言结构,它在堆上动态分配内存并使用构造函数初始化内存.除了名为"placement new"的表单之外,新尝试在堆上为新数据分配足够的内存.如果成功,它会初始化内存并将地址返回给新分配和初始化的内存.但是,如果new无法在堆上分配内存,则会抛出std :: bad_alloc类型的异常.这消除了显式检查分配结果的需要.调用delete的调用必须在每次调用new时调用析构函数并将new分配的内存返回给堆,以避免内存泄漏.

placement new应该是解决方案,但它没有提到如何做到这一点.

PS 2:我知道这可以通过stdlib的vector类来完成,但是我故意避免使用它.

Pup*_*ppy 7

你需要使用一个std::vector.在这种情况下,你可以push_back随心所欲,例如

std::vector<BattlePoint> x;
x.push_back(BattlePoint(1, 2));
Run Code Online (Sandbox Code Playgroud)

如果你曾经发现自己使用new[],delete或者delete[],立即重构你的程序删除这样的.几乎在任何可想象的方式中,它们都是非常不安全的.相反,使用资源管理类,如std::unique_ptr,std::vectorstd::shared_ptr.

经常new 可以在涉及某些情况下非常有用unique_ptr,但没有别的避免它.此外,新位置通常不值得.当然,如果你正在编写一个资源管理类,那么你可能不得不将它们用作底层基元,但这种情况很少而且很远.

编辑:我的错误,我没有看到你问题的最后一行.解决它:

PS 2:我知道这可以通过stdlib的vector类来完成,但是我故意避免使用它.

如果您有针对标准库的广告系列,请滚动您自己的vector替代品.但是不要没有vector上课.有一个原因必须由所有符合要求的编译器提供.

  • @Julian:不仅存在例外问题,而且C++有更高的安全标准.一般来说,C++程序应保证在编译时不会泄漏或双重删除,这比使用内存管理类更有可能.这是一个远高于"嗯,我想这次工作......"的标准远远高于C.`vector`不仅可以让你构建任何你想要的东西,并保护你免受异常,它也会保护你从泄漏和双重删除. (3认同)
  • @Julian:C没有例外.即便如此,在C中管理内存也是一件令人讨厌的麻烦. (2认同)

Xeo*_*Xeo 5

点数 = 新的战斗点 [大小]; // 这里有疑问。
PS 2:我知道这可以通过 stdlib 的向量类来完成,但我故意避免它。

肯定会有人质疑!使用std::vector. 你为什么不呢?没有理由不使用std::vector尤其是如果它解决您的问题。

std::vector<BattlePoint> bpoints;
bpoints.reserve(size); // there, only alloc'd memory, not initialized it.
bpoints.push_back(some_point); // still need to use push_back to initialize it
Run Code Online (Sandbox Code Playgroud)

我相信问题会来 - 如何std::vector只分配内存?! operator new是答案。当您使用new. new用于构造和初始化,而operator new用于分配(这就是您可以重载它的原因)。

BattlePoint* bpoints = ::operator new(size); // happens in reserve
new (bpoints[index]) BattlePoint(some_x, some_y); // happens in push_back
Run Code Online (Sandbox Code Playgroud)