Dfowj
Dfowj

Reputation: 739

C++ Incrementing a pointer into unknown memory territory

I have a query about the behavior of C/C++ dealing with blindly incrementing a pointer.

So, I have a pointer to an int as a parameter to a function

func(int* thePointer) {...

and I have a loop inside that function

while(*thePointer) {
    ++thePointer;
}

I understand that as long as there are int's in the memory beyond this pointer the loop will continue, but what if the memory belongs to part of another memory type? Say you increment into the first 4 bytes of a double. Will the int still have a value/will the loop continue in this case?

Disclaimer: I know this is very most likely bad practice. This is a purely academic question.

Upvotes: 3

Views: 1876

Answers (7)

Keith
Keith

Reputation: 6834

ISO 14882, section 5.7:

$4 For the purposes of these operators, a pointer to a nonarray object behaves the same as a pointer to the first element of an array of length one with the type of the object as its element type.

$5 When an expression that has integral type is added to or subtracted from a pointer, the result has the type of the pointer operand. If the pointer operand points to an element of an array object, and the array is large enough, the result points to an element offset from the original element such that the difference of the subscripts of the resulting and original array elements equals the integral expression. In other words, if the expression P points to the ith element of an array object, the expressions (P)+N (equivalently, N+(P)) and (P)N (where N has the value n) point to, respectively, the i+nth and i– nth elements of the array object, provided they exist. Moreover, if the expression P points to the last element of an array object, the expression (P)+1 points one past the last element of the array object, and if the expression Q points one past the last element of an array object, the expression (Q)1 points to the last element of the array object. If both the pointer operand and the result point to elements of the same array object, or one past the last element of the array object, the evaluation shall not produce an overflow; otherwise, the behavior is undefined.

Upvotes: 4

Loki Astari
Loki Astari

Reputation: 264641

Moving a pointer is dangerous if you access the memory (read or write).

Moving a pointer past the end of the current object and de-referencing the object is undefined behavior.

Single Object:

int  x;
int* xp = &x;

xp++; // Now pointing past the object.
int  y  = *xp; // Undefined behavior.

Array:

int  x[10];
int  xp = x;

while(*xp)
{   ++xp;  // Works fine the first 9 times.
}          // After that it is UB to access the memory pointed at by xp

Note: on looping

while(*xp)  // This continues while the memory pointed at
            // is not zero. As soon as a zero is found in memory
            // the loop exits.

Upvotes: 1

Javier
Javier

Reputation: 2838

I join everybody. Thinking of doing that, even with academic purposes, is opening the door for the devil. The pointer will advance the size of int each time, no matter what is in memory. When accessing that you will get garbage.

Upvotes: 1

Jonathan Wood
Jonathan Wood

Reputation: 67305

The code you have above has nothing to do with how many ints there are in memory. Your code goes until is finds the equivalent of an integer set to zero.

Yes, this is very bad practice. The results are undefined. You are more than likely to encounter memory that is not part of the expected array. And you have a high chance that you go into memory that cause a processor fault.

Upvotes: 0

Pablo Santa Cruz
Pablo Santa Cruz

Reputation: 181430

In memory there is no such thing as a int or a double. Memory is just memory: placeholder for bytes.

So, if you keep incrementing a pointer to int, you will point to the next four bytes in memory and that's it. If you attempt to use that portion of the memory through the pointer to integer, you will probably treat its content as if it were an int.

Eventually, you will point to a region of the memory not being assigned to your process and your program will exit with a SEGMENTATION FAULT.

Upvotes: 7

bmargulies
bmargulies

Reputation: 100152

If you keep incrementing, eventually you will get a SIGSEGV or the Windows Moral Equivalent. However, before you get there, you are likely to take a Cooke's Tour of whatever else is lying about in VM. Other variables, disused sandwich wrappers, whatever.

Loops like this are not just 'bad practice', they are a major source of exploits.

Upvotes: 0

Reed Copsey
Reed Copsey

Reputation: 564751

but what if the memory belongs to part of another memory type? Say you increment into the first 4 bytes of a double. Will the int still have a value/will the loop continue in this case?

The compiler doesn't care what type of memory is there. You can increment into any type of memory you choose, and it will be fine.

It will only have a problem when you try to access that memory location. If you try to set a value at the pointer location, and it's not memory allocated to your process, it will crash.

As long as the memory at the location belongs to you (ie: your program allocated it), you'll be able to set it. That being said, if the memory location wasn't something you were treating as an integer value, you'll most likely corrupt the state of some other object, which will eventually lead to bad things happening.

Upvotes: 2

Related Questions