内存泄漏,分配赋值运算符,新建,删除和C ++

时间:2013-10-20 03:02:11

标签: c++ pointers memory memory-leaks

当然可以使用newdelete在C ++中动态分配内存。如果在C ++程序中不再需要使用new动态分配的指针,则可以使用delete来动态释放计算机内存。我想,如果我的记忆正确地为我服务,Stroustrep在他的一本关于C ++的书中提到C中的mallocalloc给编译器而不是程序员提供“释放”或“与面向对象的“新”和“删除”相比,创建“内存”。如果我不删除指针,那么我会遇到一个相当阴险的内存泄漏,这是不好的。

然而,仅删除指针 - 如第二版“墙壁和镜子”中第151-153页上的Carrano,Helman和Veroff(CHV)注释 - 并没有消除指针。相反,删除会清空指针的内容,但将指针留在计算机内存空间的某处。

无论如何,CHV然后说使用NULL后指针必须设置为delete才能摆脱这个“已删除”的构造。

在这种情况下赋值运算符是否过载以接受NULL作为布尔值?换句话说,编译器告诉计算机指针应该存在于内存空间中是错误的,这意味着我告诉编译器物理上阻止占用两位空间的一堆电子通过我的计算机运行?我在这里错过了什么吗?

4 个答案:

答案 0 :(得分:4)

  

仅删除指针不会消除指针

确实没有;它会破坏指针指向的对象,并释放对象的内存。指针不受影响,最终指向无效的内存。

  

无论如何,CHV然后说使用删除后指针必须设置为NULL才能摆脱这个“已删除”的构造

不,之后指针仍然存在;但将其设置为null将确保它不指向无效的内存,这可以说更安全。当然,使用智能指针管理动态对象是一个更好的主意,所以你永远不会得到一个无效的指针。

  

在这种情况下,赋值运算符是否过载以接受NULL作为布尔值?

不,NULL不是布尔值,它是空指针常量;一个特殊的指针值,它不指向任何东西。

  

换句话说,编译器告诉计算机指针应该存在于内存空间中是错误的,这意味着我告诉编译器物理地停止占用两位空间的一堆电子运行通过我的电脑?

呃,什么?不,它只是告诉指针不指向任何东西。它肯定不会阻止任何电子占据任何空间。

  

我在这里错过了什么吗?

我认为你缺少的主要想法是指针及其指向的东西是单独的对象,具有不同的生命周期。 delete将销毁具有动态生命周期的对象,但不会销毁用于引用它的指针。

答案 1 :(得分:1)

一些历史可能会有所帮助。首先,有C,有malloc等,例如:

char *ptr = malloc(100);
strcpy(ptr, "hello, world!");
free(ptr);
printf("%s\n", ptr);   /* BAD - but will PROBABLY print "hello, world!" */

malloc分配100个字节,strcpy填充它,free()释放它。 “deallocate”中涉及的内容仅仅意味着该内存现在可以通过另一次调用malloc来重用。

free()不会重置任何指针,也不会清除内存 - 因此上面的printf可能仍会打印字符串,因为没有任何内容(可能)已经更改。当然,任何编写类似内容的程序员都应该被解雇。

为了避免使用不当,因为free()不会重置指针,所以一旦我们释放一些内存,我们就可以重置它们:

free(ptr);
ptr = NULL;
printf("%s\n", ptr);   /* Now we get a NULL pointer exception - which is what we want */

我们想要Null指针异常,因为在free()之后我们不应该使用ptr的值。

使用C ++,所有这些参数都是相同的。 delete除了free之外还做了一些事情 - 主要是调用对象析构函数等,但基本相同。指针不会被重置,内存仍然存在 - 你想知道你是否正在访问未分配给你的内存 - 最好的方法是在删除对象时将指针设置为null。 / p>

答案 2 :(得分:0)

使用nullptrNULL的无效指针用于防止双删除时发生崩溃,而不是释放指针实际占用的内存(指针,而不是它指向的内存)。实际指针停止存在的唯一时间是范围的结束。

答案 3 :(得分:0)

指针本身的生命周期与所有其他变量一样,由范围控制。

void someFunc()
{
    int* ptr;

}//ptr dies after this bracket

因此,请务必记住在指针超出范围之前释放指针所指向的内存,否则您永远无法再次访问它!