繁体   English   中英

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

[英]C++ free all memory used by 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 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;
}

谢谢!

您只需要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; ,它们会导致内存泄漏。

一个好的经验法则:调用delete每一个newdelete[]为每个new[]和你是安全的。

在此示例中:

struct CoordLocation
{
    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);

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

指针本身分配有自动存储持续时间,那里没有任何可用空间。 结构是这三个字段,在调用delete时将释放它们。 您只能对new返回的内容调用delete

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

但是要注意的一件事是这样的情况(在C ++中,您不会创建这样的类型,但是该示例是相关的):

struct Foo {
    char *str;
};

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

delete f;

在这种情况下,您有泄漏。 您删除f ,该f由足够的内存来容纳单个char* ,但是char*指向的内容也已动态分配。 因此,您也需要释放它:

delete f->str;
delete f;

同样,在C ++中,您可能不会以这种方式设计类型,而是偏爱诸如std::string类的类型以及诸如RAII之类的原理,但是该示例是相关的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM