0

如果我使用的是 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 种情况下,内存都被正确释放。

4

5 回答 5

8

前两个是等价的。您没有将任何东西称为函数,您只是在表达式的一部分周围放置了一组多余的括号——大约相当于1+2*3vs.1+(2*3)或(太常见的)return(23);vs.return 23;

在第二个中,您在[]添加括号时省略了,导致未定义的行为。

后者的典型(但绝对不能保证)结果将释放内存块本身,但无法为数组中的项目调用析构函数。在您的情况下(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;
}

结果:

test 1
create
create
create
create
create
destroy
destroy
destroy
destroy
destroy
test 2
create
create
create
create
create
destroy

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

于 2013-10-02T17:59:56.763 回答
1

delete(wszChar)不是调用函数 - 它是删除运算符,表达式(wszChar)作为操作数。

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

于 2013-10-02T18:00:04.503 回答
1

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

delete wszChar;

您的第二个示例使用deletewhere delete[]should be used,导致未定义的行为

于 2013-10-02T18:00:10.847 回答
1

没有不同。使用()并不意味着调用一个函数,它只是结合了运算符()delete

delete (wszChar);

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


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

于 2013-10-02T18:00:48.817 回答
1
delete(wszChar);

相当于:

delete wszChar;

请记住,如果您以这种方式混合,则应调用每个 a 和应new调用delete每个new[]a :delete[]

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

行为未定义

于 2013-10-02T18:02:01.320 回答