-8

Say I have pointer array:

char* buf = new char[256];

what will happen to array pointer's value/size if i do

buf -= 100;
nuclearc
  • 21
  • 1
  • 9

2 Answers2

4

+, +=, - and -= move a pointer around.

The pointer char* ptr = new char[256] points at the start of a block of 256 bytes.

So ptr+10 is now a pointer poimting 10 in, and ptr+=10 is the same as ptr = ptr+10.

This is called pointer arithmetic.

In C++, poimter arithmetic is no longer valid if the result takes you out of the object the pointer is pointing within, or one-place-past-the-end. So ptr-0 to ptr+256 are the only valid places you are allowed to generate from ptr.

ptr-=100 is undefined behaviour.

In C++, most implementations currently active implement pointers as unsigned integer indexes into a flat address space at runtime. This still doesn't mean you can rely on this fact while doing pointer arithmetic. Each pointer has a range of validity, and going outside of it the C++ standard no longer defines what anything in your program does (UB).

Undefined Behaviour doesn't just mean "could segfault"; the compiler is free to do anything, and there are instances of compilers optimizing entire branches of code out because the only way to reach them required UB, or because it proved that if you reached them UB would occur. UB makes the correctness of your program bassically impossible to reason about.

That being said, 99/100+ times what will happen is that ptr-=100 now points to a different part of the heap than it did when initialized, and reading/writing to what it points at will result in getting junk, corrupting memory, and/or segfaulting. And doing a +=100 will bring ptr back to the valid range.

The block of memory won't be bothered by moving ptr, just ptr won't be pointing within it.

Yakk - Adam Nevraumont
  • 262,606
  • 27
  • 330
  • 524
1

The standard says that even just trying to calculate a pointer that goes outside the actual boundaries of an array (and the "one past last" value, which is explicitly allowed, although not for dereferencing) is undefined behavior, i.e. anything can happen.

On some bizarre machines, even just this calculation may make the program crash (they had registers specifically for pointers, that trapped in case they pointed to non mapped pages/invalid addresses).

In practice, on non-patological machines calculating that pointer won't do much - you'll probably just obtain a pointer to an invalid memory location (which may crash your program when trying to dereference it) or, worse, to memory you don't own (so you may overwrite unrelated data).

The only case where that cose may be justified is if you have "insider knowledge" about the memory allocator (or you have actually replaced it with your own, e.g. providing your own override of the global new operator), and you know that the actual array starts before the returned address - possibly storing there extra data.

Matteo Italia
  • 123,740
  • 17
  • 206
  • 299