0

有问题的代码如下:

标题:


  class Vec3d : public Object {
    public:
      static linearalgebra::Vec3d* X_AXIS;
      static linearalgebra::Vec3d* Y_AXIS;
      static linearalgebra::Vec3d* Z_AXIS;
      static linearalgebra::Vec3d* AXES[3];

      static int f();
  };

执行:

  Vec3d* Vec3d::X_AXIS = new Vec3d();
  Vec3d* Vec3d::Y_AXIS = new Vec3d();
  Vec3d* Vec3d::Z_AXIS = new Vec3d();
  Vec3d* Vec3d::AXES[3] = {Vec3d::X_AXIS, new Vec3d(),Vec3d::Z_AXIS};

int Vec3d::f() { X_AXIS = AXES[2]; }

有没有办法不使用这些 new() 运算符,但不添加任何新的辅助变量?

类型必须完全一样,才能与程序的其余部分兼容。

编辑:从答案中猜测,如果没有使用辅助变量,则必须使用 new() 。这是真的吗?因此,我可能会添加辅助变量。无论如何,这是一个编译器生成的代码,所以没问题,只要标题是可读的。

以下可以吗?现在 Valgrind 说没有泄漏。


  static Vec3d INIT_X_AXIS;
  static Vec3d INIT_Y_AXIS;
  static Vec3d INIT_Z_AXIS;
  static Vec3d INIT_AXES_1;

  Vec3d* Vec3d::X_AXIS = &INIT_X_AXIS;
  Vec3d* Vec3d::Y_AXIS = &INIT_Y_AXIS;
  Vec3d* Vec3d::Z_AXIS = &INIT_Z_AXIS;
  Vec3d* Vec3d::AXES[3] = {Vec3d::X_AXIS, &INIT_AXES_1, Vec3d::Z_AXIS};
4

7 回答 7

1

它们已分配,因此您在退出时泄漏。您可以在 Vec3d 上创建一个静态方法以在关闭时处理内存(在程序退出之前调用它)。

于 2011-07-08T09:24:39.560 回答
1

如果您想保留这样的所有内容,则可以这样做(这不是好的设计,但应该可以)。我没有尝试构建,但应该没问题。

Vec3d* Vec3d::X_AXIS = NULL;
Vec3d* Vec3d::Y_AXIS = NULL;
Vec3d* Vec3d::Z_AXIS = NULL;
Vec3d* Vec3d::AXES[3] = { 0 };

namespace {
    const struct Initializer {
        Initializer() {
            static Vec3d x, y, z;
            AXES[0] = X_AXIS = &x;
            AXES[1] = Y_AXIS = &y;
            AXES[2] = Z_AXIS = &z;
        }
    } Init;
}
于 2011-07-08T09:32:39.487 回答
1

如果这些指针永远不会被释放,在 C++ 中可以吗?

定义“确定”。你的程序会起作用吗?是的。这是个好主意吗?不!

在我看来,您最好这样做:

class Vec3d : public Object {
public:
    static linearalgebra::Vec3d xAxisMemory;
    static linearalgebra::Vec3d yAxisMemory;
    static linearalgebra::Vec3d zAxisMemory;
    static linearalgebra::Vec3d axesMemory[3];

    static linearalgebra::Vec3d* X_AXIS;
    static linearalgebra::Vec3d* Y_AXIS;
    static linearalgebra::Vec3d* Z_AXIS;
    static linearalgebra::Vec3d* AXES[3];

    static int f();
};


Vec3d Vec3d::xAxisMemory;
Vec3d Vec3d::xAxisMemory;
Vec3d Vec3d::xAxisMemory;
Vec3d Vec3d::axesMemory[3];

Vec3d* Vec3d::X_AXIS = &xAxisMemory;
Vec3d* Vec3d::Y_AXIS = &yAxisMemory;
Vec3d* Vec3d::Z_AXIS = &zAxisMemory;
Vec3d* Vec3d::AXES[3] = {&axesMemory[0], &axesMemory[1], &axesMemory[2]};
于 2011-07-08T09:32:04.523 回答
1

任何获得但未归还的内存资源都被认为是内存泄漏。new()因此,如果您使用除非您通过调用释放分配的内存来获得动态内存,否则您delete()将导致内存泄漏。

您有哪些选择?

您可以有一个静态方法,该方法在每个资源上调用 delete 以在退出程序之前显式释放分配的内存。

更好的选择是:
您应该考虑使用智能指针而不是原始指针。
使用智能指针 使用智能指针后,您不必费心delete显式调用。一旦没有对这些静态类型的剩余引用,它们将被隐式删除。这样,每个资源本身都会处理其释放。

于 2011-07-08T09:25:57.870 回答
0
  1. 使用智能指针来处理自动内存释放

  2. 添加一个静态函数来释放内存并在“atexit”中注册

于 2011-07-08T09:25:06.363 回答
0

如果你之后不释放内存,new那就是内存泄漏。你必须delete/delete[]

如果您想禁止使用newfor Vec3d,则将它们设为private未实现:

class Vec3d {
private:
  void* operator new (std::size_t); // don't implement it
public:
//...
};

这样编译器将不允许使用new()on Vec3d。您也可以考虑在自动存储上创建此变量。只是不要将它们声明为指针,而是作为对象。

static linearalgebra::Vec3d X_AXIS;
于 2011-07-08T09:23:37.720 回答
0

It is a memory leak. Any variable allocated with new must be deleted with the delete keyword.

You could try to make another static variable that acts as a reference counter. In the constructor you add +1 to it, and in the destructor you do -1 on it. In the destructor after doing the minus one you check if the variable is 0 and if so.. you call delete on the static members.

Header:

static int  _refCount;

Implementation:

int Vec3d::_refCount = 0;

Vec3d::Vec3d()
{
    _refCount += 1;
}

virtual Vec3d::~Vec3d()
{
    _refCount -= 1;
    if (_refCount == 0)
    {
        //delete all allocated memory in static variables
    }
}

..or you could just use a Smart Pointer implementation.

于 2011-07-08T09:26:51.053 回答