17

In C++ is there any difference between the pointers p and q in the below code?

int* p = new int;
int* q = new int[5];

I understand that one allots new memory for a single int and the second allots memory for an array of 5 ints, but fundamentally is there any difference between a pointer pointing to a single int and one pointing to an array of ints?

I got this doubt because I read that one must use delete[] q to free up memory pointed to by q but just delete p for the single int pointed to by p. What would happen if I used delete q?

strider0160
  • 519
  • 1
  • 6
  • 15
  • 1
    sloppy speaking, `delete` doesnt do much to the pointer itself but to the stuff it points to and deleting an `int` is not the same as deleting an array of ints – 463035818_is_not_an_ai May 20 '19 at 12:08
  • 2
    Some implementations will track the size of the allocation of the array in the address before the pointer returned. This is an implementation detail not defined by the standard. You must remember to use the correct form of delete however. – drescherjm May 20 '19 at 12:09
  • @drescherjm I thought of something like this but i was unsure of how the compiler would find the size of the allocation. Could you point me to more info on this? – strider0160 May 20 '19 at 12:35
  • I don't have a good reference. This answer talks a little more about how this could work: https://stackoverflow.com/a/1913393/487892 – drescherjm May 20 '19 at 12:37
  • @drescherjm Your answer is more informative than the current answer, so if you can, please write it as an answer, so that I can mark it as accepted and close the question. – strider0160 May 20 '19 at 12:47
  • @strider0160 fyi question dont get "closed" when you accept an answer. New answers can be always added and thats a good thing. Moreover, you have the possibility to change your mind later and accept a different answer – 463035818_is_not_an_ai May 20 '19 at 12:54
  • Both pointers point to a single `int`, but one of those `int`s also happens to be the first element of an array. A pointer to an array of five `int`s has the type `int (*)[5]`. – molbdnilo May 20 '19 at 13:18

3 Answers3

18

The pointers themselves are completely indistinguishable. That's why you must remember to match new/delete and new[]/delete[].

Mismatching them triggers undefined behaviour.

P.W
  • 26,289
  • 6
  • 39
  • 76
Quentin
  • 62,093
  • 7
  • 131
  • 191
5

When using new [] some c++ implementations will track the size of the allocation of the array in the address before the pointer returned. This is an implementation detail not defined by the standard.

The following answer describes this possible implementation in a little more detail: How could pairing new[] with delete possibly lead to memory leak only?

You must always match new with delete and new [] with delete []. It is Undefined Behavior to mix these.

drescherjm
  • 10,365
  • 5
  • 44
  • 64
  • This is patently wrong, the standard specifies that there are multiple differences between the pointers, and conflating them consequently leads to undefined behaviour. What's true is that the implementation isn't obliged to notify the programmer when they forget the differences. – Konrad Rudolph May 20 '19 at 16:55
2

In C++ is there any difference between the pointers p and q in the below code?
There is no visible difference between the pointers, but there certainly is one, and it is important. One is a pointer to an integer, the other is a pointer to an integer, which is also the first element in an array of a given size.

Unluckily, given only the pointer, you have no way of telling.

What would happen if I used delete q?
Probably nothing, but possibly a lot.

First of all, calling delete instead of delete[] will call the destructor exactly once, on the first element of the array, rather than on every element as it should. Now, the destructor for a trivial type like int doesn't do anything, so... as far as that goes, there is no real difference. There is, however, a huge difference for not-so-trivial types where the destructor (or chain of destructors) actually does something.

Second, you are interfering with proper deallocation of the underlying raw memory block. This can (and sometimes does) cause a hard crash. It might even cause a crash which occurs at a later time, in an unrelated, innocent piece of code, due to corruption earlier. Try and debug that.

Or, you might get a silent memory leak, it depends on the implementation and sometimes even on your "luck" in the particular case (e.g. hit a page boundary or not).
Because, well, allocating and freeing an array and allocating and freeing a single element just isn't the same thing. They are (usually) implemented slightly differently, and while the implementation may be able to cope with mismatched new/delete, that isn't guaranteed. You might get different behavior in the debugger compared to normal exection, too, whatever, anything.

Calling the wrong form of delete means invoking undefined behavior. Which basically means anything can happen. That includes "nothing" as well as "problem which is impossible to debug". It also includes the possibility of the compiler optimizing maliciously or just stripping out the entire surrounding function, or assuming a certain condition to be always-true. Which can lead to very nasty surprises on which you spend days and days trying to figure out what's going on.

Damon
  • 67,688
  • 20
  • 135
  • 185