Search code examples
c++arrayspointersdereference

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

  • 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.