有问题的代码如下:
头:
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};
答案 0 :(得分:1)
他们被分配,所以你在退出时泄漏。你可以在Vec3d上创建一个静态方法来在关机时处理内存(在程序退出之前调用它)。
答案 1 :(得分:1)
获取但未返回的任何内存资源都被视为内存泄漏。因此,如果您使用new()
获取动态内存,除非您通过callnig delete()
释放已分配的内存,否则会导致内存泄漏。
您有哪些选择?
您可以使用静态方法,在每个资源上调用delete,以便显式在退出程序之前释放已分配的内存。
更好的选择是:
您应该考虑使用智能指针而不是原始指针
使用智能指针一旦使用智能指针,您就不必为显式调用delete
而烦恼。一旦没有对这些静态类型的剩余引用,它们将被隐式删除。这样每个资源本身都会处理它的释放。
答案 2 :(得分: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]};
答案 3 :(得分: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;
}
答案 4 :(得分:0)
如果在new
之后没有释放内存,那么就是内存泄漏。您必须delete/delete[]
。
如果您不允许new
使用Vec3d
,请将其设为private
并且未实现:
class Vec3d {
private:
void* operator new (std::size_t); // don't implement it
public:
//...
};
这样编译器就不允许在new()
上使用Vec3d
。您也可以考虑在自动存储上创建此变量。只是不要将它们声明为指针,而是将其声明为对象。
static linearalgebra::Vec3d X_AXIS;
答案 5 :(得分:0)
1)使用智能指针处理自动内存释放
2)添加一个静态函数来释放内存并在“atexit”中注册它
答案 6 :(得分:0)
这是内存泄漏。必须使用delete关键字删除使用new分配的任何变量。
您可以尝试创建另一个充当引用计数器的静态变量。在构造函数中,为它添加+1,并在析构函数中对其执行-1。在执行减1后的析构函数中,检查变量是否为0,如果是,则在静态成员上调用delete。
部首:
static int _refCount;
实现:
int Vec3d::_refCount = 0;
Vec3d::Vec3d()
{
_refCount += 1;
}
virtual Vec3d::~Vec3d()
{
_refCount -= 1;
if (_refCount == 0)
{
//delete all allocated memory in static variables
}
}
..或者您可以使用Smart Pointer实施。