Question

By referring to http://www.cplusplus.com/doc/tutorial/dynamic/, it is said that the new operator returns a pointer to the beginning of the new block of memory allocated. Let's assume again that any pointer has the feature of pointer arithmetic, which can make it true that p + 1 points to the next position in memory if p is a pointer. Based on the above assumptions, I have tried the following block,

#include <iostream>
using namespace std;
int main(){
    int * ptr = (new int [4]) + 1;
    ptr[3] = 2;
    cout << ptr[3] << endl;
    /*Before delete the dynamic allocated memory, 
      it should be necessary to let ptr point to the 
      beginning of it, add one line to do that:
      --ptr;*/
    delete [] ptr;
}

I expected that ptr[3] should goes beyond the range of newly allocated memory. However, the result still give 2. Why the pointer arithmetic become useless? Or is it really new Type returns an object of *Type?

Thanks for any help.

Was it helpful?

Solution

I expected that ptr[3] should goes beyond the range of newly allocated memory.

It does indeed. You need to be careful not to do that, since (as you've noticed) that's an error that often can't be detected. Dynamic analysis tools like valgrind can help diagnose these problems, but not perfectly.

However, the result still give 2.

That means that there happened to be accessible memory beyond the end of the array, so the invalid access couldn't be detected. Instead, it overwrote memory that didn't belong to the array - perhaps it was unused, or perhaps you've overwritten some other data, which will cause baffling errors later.

Why the pointer arithmetic become useless?

It's as useful as any pointer arithmetic. Pointer arithmetic can't detect the end of an array, so you get undefined behaviour if it takes you out of range.

Or is it really new Type returns an object of *Type?

new Type[] returns a Type* pointer to the allocated array. That behaves just like any other pointer, so adding one gives you a pointer to the second element.

delete [] ptr also gives undefined behaviour, since ptr no longer points to the start of an allocated array.

OTHER TIPS

Going beyond boundary is undefined behavior.

You may get different results when compiled by differet compiler, different compilation flags, even running at different time. You computer may blow off and your monitor may burn.

Return a correct value is one of undefined behaviors too.

C/C++ allows you to assign/read values to/from out of bounds memory, as this is undefined behavior.

For instance, this is valid code:

int *array = new int[10];
array[10] = 5;
std::cout<<array[10];

However, doing this you could damage other data structures, if they happen to have memory allocated adjacent to your array.

int * ptr = new int [4];

will point to ptr[0], so

int * ptr = (new int [4]) + 1;

will pont to ptr[1] and you will not be able to free ptr unless you do something like delete (ptr--);

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top