0

I'm trying to wrap my head around why this works. As far as I understand when i dynamically allocate 3 ints it shouldn't let me add more after index 2 but the code below compiles and runs perfectly well. Why is this?

#include <iostream>
int main() {
    int* nums = new int[3];
    nums[0] = 5;
    nums[1] = 6;
    nums[2] = 5;

    nums[3] = 7;
    nums[4] = 8;

    for(int i = 0; i <= 4; i++) {
        std::cout << nums[i] << std::endl;
    }

    delete nums;

    return 0;
}
cainsr2
  • 11
  • 1
  • 2
  • 4
    Undefined behavior. Don't do this – tkausl Oct 25 '17 at 23:05
  • 3
    Use std::vector instead of new. Then you wouldn’t have used the wrong delete. –  Oct 25 '17 at 23:07
  • 1
    C/C++ does not enforce bounds checking, you're accessing an undefined chunk of memory that might or might not hold something else. Try this using a struct with { int a[3], b[3] } and notice that &a[4] might have the same address as &b[1] – Dave S Oct 25 '17 at 23:08
  • Please refer to this link: https://stackoverflow.com/questions/1239938/accessing-an-array-out-of-bounds-gives-no-error-why Possibly duplicate of this question. – Usama Chaudhary Oct 25 '17 at 23:09
  • Ah I see, thanks guys for the quick reply! – cainsr2 Oct 25 '17 at 23:11
  • @cainsr2 -- Think of it this way -- if you had your driver's license suspended, does that mean you can't get into a car and drive it, possibly for hundreds of miles without being stopped once by a policeman? Of course you can. Does it mean it is legal for you to do so? Of course it isn't legal. C++ works in this fashion -- you're "allowed" to do things that are undefined, and you may have nothing go wrong, or your whole program may collapse. – PaulMcKenzie Oct 25 '17 at 23:21
  • By the way, `delete nums;` should be `delete[] nums;`. – aschepler Oct 25 '17 at 23:22
  • @manni66 The availability of better options like `std::vector` is not a valid excuse for not understanding which delete operator to use. It's still an important concept to understand. Using vector doesn't help OP understand that. – Millie Smith Oct 25 '17 at 23:25
  • @MillieSmith how do you know that the concept is not understood? –  Oct 25 '17 at 23:27
  • @manni66 I'm guessing I suppose based on the fact that OP doesn't know buffer overflows will compile but are undefined behavior. Which I think is a pretty reasonable guess. – Millie Smith Oct 25 '17 at 23:29

2 Answers2

0

As mentioned in the comments you're accessing additional memory and assigning values to it on lines:

nums[3] = 7;
nums[4] = 8;

Since you allocated 3 slots for your array it allocated memory required, but when you're using pointers you're accessing the memory location directly so you can freely jump out of your array memory space and venture into unknown memory.

This is VERY BAD practice as you don't know what's located on those memory slots.

anteAdamovic
  • 1,462
  • 12
  • 23
-1

C++ is an unsafe language. If you allocate 3 ints on the heap, you have to make sure that you do not later try to write to where there would be a 4th or 5th int. C++ will allow you write there even though it's a bad idea.

One solution to this problem is to almost never use the pointers built into the language. You can make, or use someone else's, pointer class. It should be a template class, that way you can make a pointer to anything: pntr<int>, pntr<Car>,pntr<ostream>, pntr<string>, etc...

Overload:

  • operator new[]
  • the deference operator,
  • operator bracket-bracket
  • etc...

Your pointer class can throw an error if you try to write to where you are not supposed to.

#include <iostream>
#include "pntr.h"

int main() {
    pntr<int> nums = new int[3];
    nums[0] = 5;
    nums[1] = 6;
    nums[2] = 5;    
    nums[3] = 7; // THROWS AN ERROR
    nums[4] = 8; 

    delete nums;

    return 0;
}
Toothpick Anemone
  • 4,290
  • 2
  • 20
  • 42