'Why does new int() work like an array in C++?

As far as I understand

int* p = new int();

Is something like creating an int with a constructor. If so why does the following code work like an array?

int* p = new int();
    
*p = 5;
    
p[1] = 15;
    
for (int i = 0; i < 2; i++)
    cout << p[i] << endl;
5
15


Solution 1:[1]

Why does new int() work like an array in C++?

p[1] is equivalent to *(p + 1), it simply dereferences the pointer to access the value stored in the memory location where it points to, the notation is similar to array notation, it's allowed and is preferred to pointer notation because it's more readable.


As far as I understand

 int* p = new int();

Is something like creating an int with a constructor.

Yes, but that's not all, you are also allocating memory for exactly one int and assigning the memory address to the pointer p.

Note that it could be int* p = new int[2], it's the exact same pointer, but in this case the memory block returned by new is good for 2 int instead of just the one, incidentally this would make the rest of your code valid, except for the fact that you do not delete the memory allocated by new, which would cause a memory leak.

Now consider the following code:

int arr[10];
int* p = arr;

In this case you have the exact same pointer, but it will be pointing to the first element of an array with automatic storage duration.

The pointer does not know how much memory it points to because it's pointing to the first element in a given memory block, for the program it's not apparent how big that block is. When indexing the pointer, it's the programmer responsability to not overrun that memory.

One important thing to note is that, in some cases, where other languages might stop you from putting your foot in it, C++ does not, it trusts the programmer to produce correct code, that's why it's usually harder to be a C++ programmer.


As already pointed out your program incurs in undefined behavior while accessing p[1]. Note the first phrase of the linked resource, it simply states:

[Undefined behavior] renders the entire program meaningless if certain rules of the language are violated

That is the case here, the memory you are accessing is located out of the bounds defined by your manual memory allocation. The fact that the output is what you expect is a matter of (bad, I would say) luck, it may output the correct result today and crash tomorrow, who knows.

You can see by the above examples that this situation would be hard to diagnose, it's the exact same type for the 3 sample cases.

In any case there are ways to diagnose memory problems like this, examples are valgrind and gcc address sanitizer, among others.


On a side note, avoid using raw pointers, use smart pointers or one of the C++ containers if possible.

I would also encourage you to acquire some knowledge on the related topic of OOP RAII principles.

Solution 2:[2]

why does the following code work like an array?

It doesn't. The program has undefined behavior meaning it is still in error even if it doesn't say so explicitly and "seems to be working". This is due to the use of the expressions p[1] and p[i] in your program.

Undefined behavior means anything1 can happen including but not limited to the program giving your expected output. But never rely(or make conclusions based) on the output of a program that has undefined behavior. The program may just crash.

So the output that you're seeing(maybe seeing) is a result of undefined behavior. And as i said don't rely on the output of a program that has UB. The program may just crash.

So the first step to make the program correct would be to remove UB. Then and only then you can start reasoning about the output of the program.


1For a more technically accurate definition of undefined behavior see this where it is mentioned that: there are no restrictions on the behavior of the program.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2