C++ C++;释放结构使用的所有内存

C++ C++;释放结构使用的所有内存,c++,class,memory,dynamic,struct,C++,Class,Memory,Dynamic,Struct,快速提问;我在谷歌上搜索了一下,已经找到了一些答案,但我有点偏执,所以我想确定一下 考虑这种情况: struct CoordLocation { float X; float Y; float Z; }; int main() { CoordLocation *coord = new CoordLocation(); delete coord; return 0; } 调用delete是否也会清除X、Y、Z字段使用的内存?我找到的一些答案提到,

快速提问;我在谷歌上搜索了一下,已经找到了一些答案,但我有点偏执,所以我想确定一下

考虑这种情况:

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

int main()
{
    CoordLocation *coord = new CoordLocation();
    delete coord;
    return 0;
}
调用delete是否也会清除X、Y、Z字段使用的内存?我找到的一些答案提到,我只是删除了指针,而不是以这种方式删除了实际引用的对象。 如果

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;
}
谢谢

在本例中:

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
(ing)指针只会将内存地址标记为“freed”,它不会修改其内容。访问已释放的指针是未定义的行为。

您只需
删除
使用
新建
分配的内存即可

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
,为每个
new[]
调用
delete[]
,这样你就安全了。

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

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

<> P>一个值得注意的是,这样的情况(C++中,你不会创建这样的类型,但是这个例子是相关的):

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

delete f->str;
delete f;

再次,在C++中,你可能不会这样设计一个类型,而是喜欢像<代码> STD::String >和RaIII之类的原理,但是这个例子是相关的。< /P>也许,“将被重用。”在一个威胁的声调中说,同时在你下巴下面拿着一个闪亮的手电筒。Luchian,如果第二个或第三个

new
抛出异常,在第三个示例中会发生什么?
main
中没有异常处理程序,因此将执行
terminate
abort
并终止程序,但在此之前,是否存在内存泄漏,如
delete-coord(因此
删除X;
)永远不会执行?@BojanKomazec啊!这取决于你所说的内存泄漏是什么意思——第三个例子将创建一个双删除,如果你复制并构造一个的话。@LuchianGrigore是的,这是一个边界情况。它可能会也可能不会被视为泄漏;我还在读答案。您在那里提出了一个非常有趣的问题。您的第二个
printf
有点错误(格式标识符与参数类型不匹配)。你真的想写
printf(“%f”,*a),就像在第一个代码> Prtff中?如果使用最近的/现代编译器,最可靠的方法来确保新的内存被正确删除,就是使用C++标准库中可用的“智能”指针类型之一。std::unique_ptr和std::shared_ptr完全拥有一个新对象,并保证他们负责的对象不会泄漏。(理想情况下,您的代码中永远不会有任何原始指针)感谢您提供的关于unique_ptr的提示。我正在使用VisualC++ 2008进行工作,所以编译器不支持新的标准(在STD命名空间中找不到UnQuyQPTR)。我会用老办法,至少以后再说。是的,我在第二次打印时犯的错误F:)
delete f->str;
delete f;