Pointer incrementing in C++
Asked Answered
A

5

5

What does this mean: that a pointer increment points to the address of the next base type of the pointer?
For example:

p1++;  // p1 is a pointer to an int

Does this statement mean that the address pointed to by p1 should change to the address of the next int or it should just be incremented by 2 (assuming an int is 2 bytes), in which case the particular address may not contain an int?
I mean, if p1 is, say, 0x442012, will p1++ be 0x442014 (which may be part of the address of a double) or will it point to the next int which is in an address like 0x44201F?

Thanks

Adrieneadrienne answered 27/6, 2011 at 11:52 Comment(0)
C
10

Pointer arithmetic doesn’t care about the content – or validity – of the pointee. It will simply increment the pointer address using the following formula:

new_value = reinterpret_cast<char*>(p) + sizeof(*p);

(Assuming a pointer to non-const – otherwise the cast wouldn’t work.)

That is, it will increment the pointer by an amount of sizeof(*p) bytes, regardless of things like pointee value and memory alignment.

Centralization answered 27/6, 2011 at 11:59 Comment(0)
S
4

The compiler will add sizeof(int) (usually 4) to the numeric value of the pointer. If p1 is 0x442012 before the increment, then after the increment it will be 0x442012 + 4 = 0x442016.

Mind you, 0x442012 is not a multiple of 4, so it is unlikely to be the address of a valid four-byte int, though it would be fine for your two-byte ints.

It certainly won't go looking for the next integer. That would require magic.

Soldierly answered 27/6, 2011 at 11:56 Comment(0)
B
3

p1++ gives rise to assembly language instructions which increment p1 by the size of what it points to. So you get

(char *)p1 = (char *)p1 + sizeof (object pointed to by p1)

(When this question was answered) Typically an int is 4 bytes, so it would increment by 4, but it depends on the sizeof() on your machine.

It does not go to "the next int".

An example: assume a 4 byte address and p1 = 0x20424 (where p1 is an int*). Then

p1++

would set the new value of p1 to 0x20428. NOT 0x20425.

Bacteroid answered 27/6, 2011 at 11:56 Comment(12)
No. p1++ means p1 += 1, nothing else.Centralization
@Konrad: Well, unless you overload the ++ operator. Ah, the joys are redefining the meaning of operators (and a great way to make enemies) ;-)Deficient
@Deficient Even that won’t change the meaning since you cannot change the meaning of operators, so on a pointer, ++ will always have the same effect.Centralization
@Konrad: class p { public: void operator++(int){exit(0);}};int main (){p a; a++; std::cout << "End" << std::endl;}; There, a++ now quits the program. I've seen programmers overload the ^ operator on a vector3d class to implement cross products! I know, it's a crime against programming.Deficient
@Deficient The whole discussion is about p/p1 being a pointer. Otherwise the answer would be even more wrong because obviously ++ doesn’t in general add sizeof whatever.Centralization
@KonradRudolph You said "no", but Scott's definition seems correct. It does not just add '1'. I just tried it; it added 4 to my pointer. I had 0x7fa28d402780 and then I had 0x7fa28d402784. Doesn't that mean it adds sizeof(whatever) to the value, not 1?Gorgonzola
@GregSchmit That's not how pointer arithmetic works. p++ adds 1 to the pointer value. But you (and Scott) seem to think that the 1 refers to 1 byte. It doesn't. See my answer.Centralization
@KonradRudolph I thought pointers were unsigned integers, so if 4 is added, the the value was incremented by 4. It's not as if the values don't exist in between. If I have an int pointer on my machine, incrementing it adds 4 to the value, but I can manually set it to a value in between. It just seems like this answerer said exactly what you said up top. Then you said 'no'.Gorgonzola
@GregSchmit Ah, that’s where the confusion stems from. So: pointers are not unsigned integers. Pointers are pointers — a distinct type! Under the hood, many/all platforms implement pointers as unsigned integers. But p++ isn’t performed under the hood, it’s performed in C++ space. And it is equivalent to p += 1, not to p += 4 or anything else. p += 1 in turn is translated under the hood to an increment of the pointer value by the pointee object size. Of course his isn’t always 4, and the type of the address implementation has nothing to do with it.Centralization
@GregSchmit And, to make this perfectly clear: this answer doesn’t say the same as my answer at all. My answer is talking about the under-the-hood pointer address (which is equivalent to writing the C++ code reinterpret_cast<char*>(p)), not the C++ pointer itself. These are fundamentally different things.Centralization
@KonradRudolph That makes sense; yeah, I just tried to do p+=sizeof(*p) and it ends up going sizeof(*p) squared spaces, since you're (for int 4-byte as example) telling it p+=4 and then under the hood it increments the raw data 4 for each one of those. I understand better now why it is wrong to say that it increments 4. Thanks.Gorgonzola
@KonradRudolph The intention of my answer was to show what was happening under the hood - I updated it and hopefully made it more clear.Bacteroid
N
1

If p1 is pointing into the element of index n of an array of objects of type int (a non-array object counts as an array of length 1 for this purpose), then after p1++, p1 is either:

  • Pointing to the element of index n+1 if the array is of length greater than n+1.
  • The 'past-the-end' address of the array, if the array is of length exactly n+1.

p1++ causes undefined behavior if p1 is not pointing to an element of an array of objects of type int.

The only meaning that the C and C++ languages give to the notion of "address" is the value of a pointer object.

Any relationship that C/C++'s notion of address has to the notion of a numeric addresses you'd consider in assembly language is purely an implementation detail (albeit, an extremely common implementation detail).

Nasty answered 28/1, 2017 at 13:18 Comment(0)
T
0

Pointer arithmetic are done in sizoeof(*pointer) multiples - that is, for a pointer to int, increment will advance to the next integer (or 4 bytes for 32 bit integers).

Taken answered 27/6, 2011 at 11:56 Comment(4)
"4 bytes for a 32 bit integer", well, that's not always true is it. Better say "(32 / CHAR_BIT) bytes in a 32 bit integer" (using the C++ definition of byte of course). But then again, who says integers are 32 bit?Deficient
There are hardly any architectures with a byte size different than 8 bits anymore. The int type is not necessarily 32 bits, but a "32 bit integer" is. I don't see you point...Taken
There are numerous micro-controllers and DSPs that have weird configurations (there's a TI chip where all types are 16 bit).Deficient
@Skizz, I didn't said they were no architectures with a byte size different than 8 - I said there are hardly any. If you look into most (and perhaps all) of the (modern) CPUs and MCUs you'd see 8-bit bytes. DSPs are indeed wierd creatures. Some are 24 or 32 bits per byte.Taken

© 2022 - 2024 — McMap. All rights reserved.