-3

In C++ my understanding is that new should be used to allocate a single variable dynamically, and that new[] should be used to dynamically allocate an array of variables.

However the following compiles and runs fine in Xcode:

#include <iostream>

int main()
{
    std::cout<<"Enter length of array: ";
    int length;
    std::cin>>length;
    int *mArray = new int;
    for(int i=0;i<length;++i)
        mArray[i] = i;
    for(int i =0;i<length;++i)
        std::cout<<mArray[i]<<std::endl;

    delete mArray;
    return 0;
}

Why does this work? Shouldn't it cause the program to crash if it is accessing memory it hasn't been allocated?

  • 3
    You are writing and reading out of bounds. If it works correctly you just got lucky, this code has undefined behavior. – Cory Kramer Aug 03 '17 at 15:13
  • 2
    If a code compile, that doesn't mean it's correct (cf undefined behaviour). – nefas Aug 03 '17 at 15:15
  • 2
    Thus is the danger of doing pointer management vs. using `std::vector`. – Khouri Giordano Aug 03 '17 at 15:15
  • Read this https://en.wikipedia.org/wiki/Undefined_behavior – Slava Aug 03 '17 at 15:16
  • 1
    Not 100% the same (code wise) but pretty close: https://stackoverflow.com/questions/1239938/accessing-an-array-out-of-bounds-gives-no-error-why – NathanOliver Aug 03 '17 at 15:21
  • Read up on UB (Undefined Behaviour) : http://en.cppreference.com/w/cpp/language/ub – Jesper Juhl Aug 03 '17 at 15:23
  • 2
    Undefined Behaviour is *undefined*. Sometimes you're unlucky, and everything appears to work. – Toby Speight Aug 03 '17 at 15:24
  • You allocated one int that lives somewhere in memory. As you start writing into nearby memory (that you do not own), it may work because hey, memory is memory, right? But it's not YOUR memory, and it may even be a read-only page. As such you could get signaled by the OS, or you could write into random space (and your memory will eventually get clobbered by something.) Do not confuse "doesn't crash" with "works correctly." Instead think, "I got unlucky& tricked into thinking bad code was ok." You did properly match new/delete, but not an array--only enough space to write *one* int value. – Chris Uzdavinis Aug 03 '17 at 15:56

1 Answers1

1

Why does this work? Shouldn't it cause the program to crash if it is accessing memory it hasn't been allocated?

This is the price of speed and flexibility of C++ - Undefined Behavior may be observed with many forms, some of them really look like your program works correctly. Problem is it appears to "work" this time and may fail next time. Or tomorrow when you update your compiler etc. It is your job not to access memory out of bound, not compiler to prevent it. Though some compilers/environment may provide additional validation that would make such access fail one way of another, it is not required by C++ language so you cannot expect to have it by default or at all.

Note: out of bounds access not validated for direct memory access (through raw pointer in this case), when you use objects like std::vector it may or may not validate bounds, depends which method or environment you use, that you should learn from documentation.

Slava
  • 43,454
  • 1
  • 47
  • 90