将delete作为运算符或函数调用有什么区别吗?

时间:2013-10-02 17:56:47

标签: c++ visual-studio-2010

如果我使用Visual Studio 2010,以下语句之间是否有任何区别:

wchar_t *wszChar = new wchar_t;
delete wszChar;

wchar_t *wszChar = new wchar_t;
delete(wszChar);

我已经查看了调试器,似乎完成了同样的事情。

如何:

wchar_t *wszChar = new wchar_t[10];
delete[] wszChar;

wchar_t *wszChar = new wchar_t[10];
delete(wszChar);

从我所见,在所有4个案例中,内存都被正确释放。

5 个答案:

答案 0 :(得分:8)

前两个是等价的。你不是把任何东西称为函数,你只是在表达式的一部分周围放置一组冗余的括号 - 大约相当于1+2*31+(2*3)或(太常见){ {1}}与return(23);

在第二种情况下,当您添加括号时,您遗漏了return 23;,导致未定义的行为。

后者的典型(但肯定是 not 保证)结果将释放内存块本身,但无法为数组中的项调用析构函数。在你的情况下(没有析构函数的[]数组)但是无法检测到。您可能还会遇到其他副作用,例如操作系统停止执行程序。

示例:

char

结果:

#include <iostream>

struct item {
    item() { std::cout << "create\n"; }
    ~item() { std::cout << "destroy\n"; }
};

int main() {
    std::cout << "test 1\n";
    item *items = new item[5];
    delete [] items;
    std::cout << "test 2\n";
    item *items2 = new item[5];
    delete items2;
}

......随后执行被操作系统暂停。

答案 1 :(得分:1)

delete(wszChar)没有调用函数 - 它是带有表达式(wszChar)作为操作数的delete运算符。

在上一个示例中,对使用array new创建的指针调用非数组删除是未定义的行为。它在您的特定示例中的工作方式相同(即,没有明显的问题)是UB可以表现出来的一种方式。如果您更改示例以使用具有析构函数的对象来执行某些实际工作而不是wchar_t,那么您将看到行为上的差异。

答案 2 :(得分:1)

它看起来像函数调用,实际上是普通的delete运算符,后跟 primary-expression (wszChar),相当于

delete wszChar;

您的第二个示例使用delete,其中应使用delete[],从而导致未定义的行为

答案 3 :(得分:1)

没有区别。使用()并不意味着调用函数,它只是组合运算符()delete

delete (wszChar);

不要忘记使用[]来避免未定义的行为。


为了澄清,请记住关键字sizeof。您可以使用sizeof(int)sizeof int

答案 4 :(得分:1)

delete(wszChar);

相当于:

delete wszChar;

请记住,对于每个new应该调用delete,并且对于每个new[]应该调用delete[],如果你这样混合:

wchar_t *wszChar = new wchar_t[10];
delete(wszChar);

行为 未定义

相关问题