C ++释放struct使用的所有内存

时间:2012-04-20 20:11:24

标签: c++ class memory dynamic struct

快速提问;我已经google了一下,已经找到了一些答案,但我有点偏执,所以我想确定。

考虑这种情况:

struct CoordLocation
{
    float X;
    float Y;
    float Z;
};

int main()
{
    CoordLocation *coord = new CoordLocation();
    delete coord;
    return 0;
}

调用delete还会清除X,Y,Z字段使用的内存吗?我发现的一些答案提到我只是删除了POINTER,而不是这种方式实际引用的对象。 如果......

struct CoordLocation
{
    float *X;
    float *Y;
    float *Z;
};

int main()
{
    CoordLocation *coord = new CoordLocation();
    delete coord;
    return 0;
}

如果我为struct的构造函数/析构函数中的每个对象手动释放内存怎么办?

struct CoordLocation
{
    CoordLocation()
    {
         *X = new float;
         *Y = new float;
         *Z = new float;
    }
    ~CoordLocation()
    {
         delete X; delete Y; delete Z;
    }
    float *X;
    float *Y;
    float *Z;
};

int main()
{
    CoordLocation *coord = new CoordLocation();
    delete coord;
    return 0;
}

我注意到了一个简单的情况,例如:

   float *a = new float;
   *a = 5.0f;
   printf("%f", *a);
   delete a;
   printf("%f", &a);

printf将打印5.0,因此a指向的变量并未完全销毁。

所以我的问题是: 在这种情况下,如何可靠地释放(因为没有内存泄漏)结构使用的所有内存?

struct CoordLocation
{
    float X;
    float Y;
    float Z;
};

int main()
{
    CoordLocation *coord = new CoordLocation();
    delete coord;
    return 0;
}

谢谢!

3 个答案:

答案 0 :(得分:19)

您只需要使用delete分配new个内存。

  

printf将打印5.0,因此a指向的变量并未完全销毁。

您实际上遇到了未定义的行为。虽然该值仍然存在,但内存已被释放并可以重复使用。

以下内容:

struct CoordLocation
{
    float X;
    float Y;
    float Z;
};
如果省略析构函数,则

无法创建内存泄漏。

你的下一个片段:

struct CoordLocation
{
    float *X;
    float *Y;
    float *Z;
};

int main()
{
    CoordLocation *coord = new CoordLocation();
    delete coord;
    return 0;
}

可能会造成内存泄漏,但不是原样。以下将:

int main()
{
    CoordLocation *coord = new CoordLocation();
    coord->X = new float();
    delete coord;
    return 0;
}

你的第三个例子

struct CoordLocation
{
    CoordLocation()
    {
         *X = new float;
         *Y = new float;
         *Z = new float;
    }
    ~CoordLocation()
    {
         delete X; delete Y; delete Z;
    }
    float *X;
    float *Y;
    float *Z;
};

int main()
{
    CoordLocation *coord = new CoordLocation();
    delete coord;
    return 0;
}

不会创建内存泄漏,因为您释放了所分配的所有内存。如果你要省略析构函数或忘记调用delete coord;,那么你就会发生内存泄漏。

一个好的经验法则:每deletenewdelete[] new[]调用{{1}},您就安全了。

答案 1 :(得分:0)

在这个例子中:

struct CoordLocation
{
    float X;
    float Y;
    float Z;
};

int main()
{
    CoordLocation *coord = new CoordLocation();
    delete coord;
    return 0;
}

内存已释放。该代码没有泄漏。在你给出的例子中,你的struct包含指针,只要你在析构函数中释放它们(就像在你的例子中那样),就不会有泄漏。

在此片段中:

float *a = new float;
*a = 5.0f;
printf("%f", *a);
delete a;
printf("%f", &a);

删除后a的值保持不变,因为delete(ing)指针只会将内存地址标记为“已释放”,因此不会修改其内容。访问释放的指针是未定义的行为。

答案 2 :(得分:0)

指针本身被分配了自动存储持续时间,那里没有什么可以释放的。结构就是那三个字段,当你调用delete时它们被释放。您只能对delete返回的内容发送new

当你分配一些内容时,你会分配足够的内存来保存它,这意味着有足够的内存来容纳它的所有字段(以及一些特定于实现的内务处理内存,但你不必担心)。删除它时,释放相同数量的内存。

有一点需要注意的是这样的情况(在C ++中你不会创建这样的类型,但是这个例子是相关的):

struct Foo {
    char *str;
};

Foo *f = new Foo();
f->str = new char[10];

delete f;

在这种情况下,您有泄漏。您删除f,其中包含足够的内存来容纳单个char*,但char*指向的内容也已动态分配。所以,你也需要释放它:

delete f->str;
delete f;

同样,在C ++中,您可能不会以这种方式设计类型,而是支持像std::string这样的类型和RAII等原则,但这个例子是相关的。