0

Really simple question, but I could not find an answer: are the following 2 expressions equivalent in C++ in terms of memory allocation?

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

So I would like to know: do I always have to delete the array no matter how I initialize it? Or can I somehow benefit from scoping and produce arrays on the stack that simply die without explicitly calling delete, as they go out of scope. And of course does it worth using scoping if possible or is it safer to always use delete?

Sesertin
  • 452
  • 2
  • 8
  • 4
    possible duplicate of [C++ Static array vs. Dynamic array?](http://stackoverflow.com/questions/2672085/c-static-array-vs-dynamic-array) – Cory Kramer Jul 23 '14 at 11:51
  • 1
    No, no and yes. Read an introductory book. There's a good list here: http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list – juanchopanza Jul 23 '14 at 11:52
  • 1
    But why not use [std::wstring](http://www.cplusplus.com/reference/string/wstring/) instead of an array? – crashmstr Jul 23 '14 at 11:53
  • std::wstring is the best choice indeed, but I just wanted to get the idea. I thought the first instance should be a stack memory place and the second a heap space, just like the explanation goes in the linked post, I started having doubts because Visual Studio debugger displays a memory address next to wide_array: 0x..... So that usually does not happen for stack variables: I looked at classes, sructs, int, char and without a new keyword there is no memory address. Except for wchar_t wide_array[10]; when there is. – Sesertin Jul 23 '14 at 12:06
  • @Sesertin You are correct about the stack and the heap. – MGA Jul 23 '14 at 12:11
  • 1
    @Sesertin That's because when you're simply looking at the value of `wide_array`, you're looking at a pointer. Which obviously points to a memory address (typically in hex representation therefore 0x...) and since new returns a pointer, you'll see an address in these cases as well. In the other cases you're looking at values. The "stack-pointer" will simply point to another memory area than the "heap-pointer". – Sambuca Jul 23 '14 at 14:52
  • @Sambuca Thanks, your comment just made things clear – Sesertin Jul 27 '14 at 14:02

1 Answers1

1

In C/C++, an array readily decays[#] into a pointer to its first element. So *wide_array and wide_array[0] are the same thing. In fact, wide_array[i] is actually defined as (or, if you like, is syntactic sugar for) (wide_array + i). So much so that i[wide_array] means the same thing as wide_array[i], which is an amusing way to obfuscate C/C++ code (but never ever do it!).

So your second example can also be referenced as ptr_wide_array[i].

That's as far as syntax goes. Now, as to what goes on under the hood:

The difference between your two examples is that the first is allocated on the stack, the second on the heap. This implies that the first one will be automatically deallocated once it goes out of scope, but the second won't be deallocated until delete[] ptr_wide_array is called (or on another pointer which was copied from ptr_wide_array). This runs a serious risk of memory leaks, especially if you start using exceptions. In general, don't use a raw new in C/C++. Use containers such as std::vector, and smart pointers.

[#] See this SO question for an explanation of how arrays and pointers are related and how arrays "decay" to pointers.

Community
  • 1
  • 1
MGA
  • 1,558
  • 14
  • 27
  • Thanks, great answer. Do you possibly some explanation for why is a heap adress is displayed next to the first example in the debugger? See my last comment under the post. – Sesertin Jul 23 '14 at 12:11
  • @Sesertin It's just an address. The stack exists in the processor's memory map, just like the heap, so things that are on the stack have addresses, just like things in the heap. – alastair Jul 23 '14 at 12:12
  • 1
    No, an array is not a pointer to the first element, at least not in C++. This is a misconception that leads to many problems. – juanchopanza Jul 23 '14 at 12:13
  • @juanchopanza Could you elaborate a bit on that? – Erbureth says Reinstate Monica Jul 23 '14 at 12:15
  • 1
    @Erbureth An array is a distinct type, which contains information on the type of elements stored but also its size. – juanchopanza Jul 23 '14 at 12:18
  • 1
    @Erbureth, We have a nice detailed description of [arrays](http://stackoverflow.com/questions/4810664/how-do-i-use-arrays-in-c) which includes the confusion around pointers. – chris Jul 23 '14 at 12:20
  • @juanchopanza is right: an array is not strictly a pointer to its first element. It's one of those conceptualizations that is useful until it breaks down :). The edit to "readily decays into" is probably more accurate. – MGA Jul 23 '14 at 12:26
  • @mga An array is not a pointer to its first element, period. It's not a "conceptualization that is useful until it breaks down", it's simply an incorrect statement. As a result of implicit conversions, however, `*wide_array` _is_ the same things as `wide_array[0]`. And instead of saying parsed into: `wide_array[i]` is defined as `*(wide_array + i)` (assuming no user defined overloads, of course---most of the time, you'll be using `std::vector`, and this identity won't hold). – James Kanze Jul 23 '14 at 14:19
  • @juanchopanza OK, but I've come across this explanation (of an array being a pointer) in several textbooks. But I've found a good reference for the difference between the two here on SO, I'll put it in my answer. Thanks for you clarification. – MGA Jul 23 '14 at 14:37