1

I have allocated 5 int space using new and trying to access just beyond that allocated boundary (array[size] = 2; ). Ideally it should throw some error but it's not.

int size = 5;
int* array = new int[size];

array[1] = 2;

//If I uncomment below line it gives me error

//array[size] = 2; 

cout << array[1] << endl;

// Why this is not an problem
cout << array[size] << endl;

delete[] array;

But when i am trying to delete this allocated space it shows me this error.

*** glibc detected *** /home/workspace/PracticeC++/Debug/PracticeC++: free(): invalid next size (fast): 0x08add008 ***
PracticeC++: malloc.c:2451: sYSMALLOc: Assertion `(old_top == (((mbinptr) (((char *) &((av)->bins[((1) - 1) * 2])) - __builtin_offsetof (struct malloc_chunk, fd)))) && old_size == 0) || ((unsigned long) (old_size) >= (unsigned long)((((__builtin_offsetof (struct malloc_chunk, fd_nextsize))+((2 * (sizeof(size_t))) - 1)) & ~((2 * (sizeof(size_t))) - 1))) && ((old_top)->size & 0x1) && ((unsigned long)old_end & pagemask) == 0)' failed.

when i tried delete after commenting array[size] = 2; line it worked fine. I am not able to understand this strange behaviour. As per my understanding delete[] operator has information about size of array so it should not go beyond that size and this error is related to situation when we try to delete same memory twice or that is not allocated by us. Can someone tell me the reason behind this error.

Deduplicator
  • 44,692
  • 7
  • 66
  • 118
Nishant Kumar
  • 2,199
  • 2
  • 22
  • 43

4 Answers4

3

Neither C nor C++ are bounds-checking, as that would degrade performance and need extra bookkeeping data. Your memory allocator might save extra information, but only for its private use and in its private format. You could have used your own / not used it at all, so it is not reliably available.
The Undefined Behavior encountered when transgressing on memory not owned is the programmers responsibility. Anything may happen.

Deduplicator
  • 44,692
  • 7
  • 66
  • 118
  • Please look at my answer. I wrote it before @Deduplicator answered and I explained exactly why `array[size] = 2` causes error, hint: new (or malloc as well) stores extra information of allocated chunk of memery and it's used by delete (of free as well)... – rzymek Apr 05 '14 at 18:54
  • 1
    @rzymek: yes, that's what happens in *practice* (with a particular implementation...), but UB covers this problem perfectly. – Karoly Horvath Apr 05 '14 at 18:55
  • UB is wide and general term. I read from OP question a request for explanation why exactly `array[size] = 2;` cause the problem, not only for general view of problem, but maybe it's only my point of view at this question. I don't want to argue, this answer is also correct but less specific. – rzymek Apr 05 '14 at 19:03
1

You overwrite some crucial information by doing this array[size] = 2;

The malloc function (or new operator as well) stores some information about the chunk of memory which you allocated just beyond allocated block. These information are used by delete when you free memory.

You get access violation error only if you read/write memory which not belong to your process. When you write to memory which is allocated by your process you don't get any errors. However you probably experience some strange and unexpected results somewhere else in your code (like in your situation here).

rzymek
  • 866
  • 7
  • 20
0

There's no real reason why the compiler should complain here since you are using pointers. You can essentially make a pointer variable point to any possible memory location allowed by the OS. A segmentation fault will occur when you go beyond the memory allocations for the program.

If you want to avoid inadvertently accessing such indices, you must use standard arrays or an even better option would be using vectors provided in C++.

gat
  • 2,872
  • 2
  • 18
  • 21
0

Writing outside the memory that you have allocated causes undefined behaviour. That means that anything can happen, and different implementations may do different things. It's not required that an error occurs during compilation or at runtime.

Presumably in the case of the implementation you are using, some information is stored by the allocator in the memory area adjacent to the memory block that was allocated to you.
Overwriting some of that information causes problems trying to free that memory.
But you really can't make any assumptions about how the program will behave at that point. That's why it's called undefined behaviour.

filipe
  • 3,370
  • 1
  • 16
  • 22