开发者

C++ Incrementing a pointer into unknown memory territory

开发者 https://www.devze.com 2023-02-11 14:09 出处:网络
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

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开发者_如何学JAVA 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.


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.


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.


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.


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.


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.


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.


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.

0

精彩评论

暂无评论...
验证码 换一张
取 消