释放内存时是不是需要使用IF语句? [复制]

Posted

技术标签:

【中文标题】释放内存时是不是需要使用IF语句? [复制]【英文标题】:Is it necessary to use IF statement when releasing memory? [duplicate]释放内存时是否需要使用IF语句? [复制] 【发布时间】:2013-05-12 00:18:36 【问题描述】:

我正在尝试理解 C++ 中的内存部分。我试图在使用下面的代码生成输出后释放内存。

问题:

是否需要使用if语句来释放内存?

代码:

int main()
    char *pc;
    int *pi;

    pc = new char('a');
    pi = new int(8);

    cout << *pc << endl;
    cout << *pi << endl;

    //What's the purpose for doing if(pc) and if (pi) below?

    if(pc)
        delete pc;
    
    if(pi)
        delete pi;
    

return 0;

我可以这样做吗? 诠释主要() 字符 *pc; int *pi;

    pc = new char('a');
    pi = new int(8);

    cout << *pc << endl;
    cout << *pi << endl;


    delete pc;
    delete pi;

return 0;

【问题讨论】:

不,delete 会自行执行空值检查。看到这个->***.com/a/4190737/1898811 强制智能指针引用。如果你使用它们,你不必担心这些。 【参考方案1】:

释放内存时需要使用IF语句吗?

不,它不是(只要您没有覆盖全局operator delete)。这很好,不会做任何事情:

int* p = nullptr;
delete p;

根据 C++11 标准的第 3.7.4/2 段:

[...] 提供给释放函数的第一个参数可能是空指针值; 如果是这样,如果释放 函数是标准库中提供的,调用无效。 [...]

但是,As suggested by chris in the comments 考虑使用智能指针,而不是通过原始指针、newdelete(或其对应的数组)执行手动内存管理。

【讨论】:

这样不行,实际上:ideone.com/ee9VS1 @BenVoigt:嗯,这不是错误吗?我希望nullptr 在上下文中转换为每个 5.3.5/1-2 的指针类型 根据代码,我更喜欢检查或断言 NULL,因为它可以指向错误条件。但是释放 NULL 是安全的。 另外,std::nullptr_t 不是类类型,因此上下文隐式转换不适用。 (即使是这样,它也会模棱两可) @BenVoigt:嗯,对 :) 谢谢,今天学到了一些东西【参考方案2】:

在您的特定代码中,不需要空值检查。

一般来说,delete (T*)0; 是否会为类型T 调用释放函数是特定于实现的。如果您的实现确实将空指针传递给解除分配函数,并且您的类型通过提供成员 operator delete 覆盖了解除分配函数,或者您获得了替换全局 ::operator delete,并且该自定义解除分配函数不处理 null指针值很好,你可能会遇到麻烦。

标准不要求自定义 operator delete 在传递空指针时不执行任何操作。它不应该失败,但它可能会写入讨厌的日志消息或例如,告诉你的老板有人没有遵循编码标准。

【讨论】:

+1 用于提及自定义删除 如果我的实现没有将空指针传递给释放函数,释放函数还会被调用吗? @Ming:它不能将不同的指针传递给释放函数。如果你写delete (p) 并且p 为空,那么编译器要么调用operator delete(p),要么什么都不调用。如果p不为null,那么编译器肯定会调用析构函数然后operator delete(p) @BenVoigt 所以在这种情况下我可以做 delete(pc); delete(pi) 那么一切都会好起来的吧? @Ming:你绝对可以做delete pc; delete pi;,因为它们一开始就不可能为空。【参考方案3】:

不,不是,但这样做被认为是一种好习惯。在现实生活场景中,由于业务需求、错误等原因,您的代码会经常更改,因此最好使用这种防御性编程策略。

您最不想看到的错误是由于您的同事更改了代码的上半部分而释放了已释放的指针而导致的难以检测的错误

【讨论】:

忘记这个检查不会导致双重释放。它只能导致释放空值。什么都不做。 @djechlin 同意,但我要指出的是关于防御性编程策略的事实,而不是特定于上面的代码 sn-p 它不防御任何东西。 基本上它是C 编程的残余,它 好的实践。但在 C++ 中,除了让代码看起来更像 C 之外,它什么也没做。我不考虑这种良好做法,也不知道有人这样做;在我看来,这一切都是由不懂 C++ 或懒得正确学习语言或编码风格的人编写的 C 代码。 在释放指针后将指针设置为 null 会给人一种错误的安全感。 int *p = new int; int *q = p; delete p; p = 0; 现在,if(q) 无济于事。正确处理指针和内存管理的代码是你设计的东西,而不是你坚持的东西,因为某些规则说你应该这样做。 “防御性”编程无法替代声音设计。

以上是关于释放内存时是不是需要使用IF语句? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

使用 ARC 时还需要释放内存吗? [复制]

删除、释放还是解除分配?

使用归档器复制 UIView - 内存释放?

在 C 中释放内存需要啥?

Python多线程 - 使用While语句运行时未释放内存

在C语言进行编程中,为啥要释放旧内存?