2014-07-23 62 views
0

真的很简单的问题,但我找不到答案:在内存分配方面,以下2个表达式在C++中是否等价?用于数组的C++内存分配

wchar_t wide_array[10]; 
wchar_t* ptr_wide_array = new wchar_t[10]; 

所以我想知道:无论我如何初始化它,我总是必须删除数组吗?或者我可以以某种方式受益于范围设定,并在堆栈中生成数组,因为它们超出了范围,因此无需显式调用delete即可死亡。当然,如果可能的话,是否值得使用范围界定,还是总是使用删除更安全?

+4

可能重复的[C + +静态数组与动态数组?](http://stackoverflow.com/questions/2672085/c-static-array-vs-dynamic-array) – CoryKramer

+1

不,不,是的。阅读介绍性书籍。这里有一个很好的列表:http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list – juanchopanza

+1

但为什么不使用[std :: wstring](http://www.cplusplus .com/reference/string/wstring /)而不是数组? – crashmstr

回答

1

在C/C++中,数组很容易衰变[#]成指向其第一个元素的指针。所以*wide_arraywide_array[0]是同样的事情。实际上,wide_array[i]实际上定义为(或者,如果您喜欢,则为语法糖)(wide_array + i)i[wide_array]意味着与wide_array[i]一样的东西,这是一种混淆C/C++代码的有趣方式(但永远不会这么做!)。

所以你的第二个例子也可以被引用为ptr_wide_array[i]

这就像语法一样。现在,至于发生了什么:

你的两个例子之间的区别是the first is allocated on the stack, the second on the heap。这意味着一旦超出范围,第一个将自动解除分配,但第二个将不会被释放,直到调用delete[] ptr_wide_array(或另一个从ptr_wide_array复制的指针)。这会造成内存泄漏的严重风险,特别是如果您开始使用异常。一般来说,不要在C/C++中使用原始的new。使用容器,如std::vectorsmart pointers

[#]请参阅this SO question了解数组和指针如何相关以及数组如何“衰减”指针。

+0

谢谢,很好的答案。你可能会解释为什么在调试器的第一个例子旁边显示堆地址?查看我在帖子下的最新评论。 – Sesertin

+0

@Sesertin它只是一个地址。堆栈存在于处理器的内存映射中,就像堆一样,所以堆栈中的东西都有地址,就像堆中的东西一样。 – alastair

+1

不,数组不是指向第一个元素的指针,至少在C++中不是。这是一个导致许多问题的误解。 – juanchopanza