Weird Pointer Outcome: Analyzing Activation Record 6

  • Thread starter Thread starter STEMucator
  • Start date Start date
  • Tags Tags
    Weird
Click For Summary

Discussion Overview

The discussion revolves around the behavior of pointer arithmetic in C, particularly focusing on the output of a provided code snippet that manipulates pointers and their associated values. Participants analyze the implications of incrementing a pointer and how it relates to memory allocation and activation records.

Discussion Character

  • Technical explanation
  • Conceptual clarification
  • Debate/contested

Main Points Raised

  • Some participants explain that incrementing a pointer, such as 'r++', results in pointer arithmetic that adjusts the memory address stored in 'r' by the size of the type it points to, which is an integer in this case.
  • Others suggest that understanding how variables are allocated on the stack is crucial to grasping why 'r' points to the same value as 'p' after incrementing.
  • One participant notes that pointer arithmetic is scaled by the type of the object pointed to, leading to different behaviors based on the pointer's type.
  • Some participants express confusion about the implications of pointer arithmetic outside of arrays, highlighting potential risks of accessing invalid memory locations.
  • There is a discussion about the typical stack allocation of local variables and how this can affect pointer behavior, with some participants providing hypothetical memory addresses for clarity.
  • Some participants argue that while pointer arithmetic can be useful in low-level programming contexts, it can also lead to errors if not used carefully, particularly when dealing with local variables.

Areas of Agreement / Disagreement

Participants generally agree on the mechanics of pointer arithmetic but express differing views on its utility and safety, especially in contexts outside of array manipulation. The discussion remains unresolved regarding the appropriateness of using pointer arithmetic in various programming scenarios.

Contextual Notes

Participants highlight that local variables in C may not be allocated contiguously in memory, which can lead to unpredictable behavior when incrementing pointers that do not reference arrays. There is also mention of the potential for runtime errors when accessing memory addresses that are not valid.

Who May Find This Useful

This discussion may be useful for programmers interested in understanding pointer behavior in C, particularly in relation to memory management and stack allocation, as well as those exploring low-level programming techniques.

STEMucator
Homework Helper
Messages
2,076
Reaction score
140

Homework Statement



Not homework, but I don't really know where else to put this.

Below is some code and it's relevant output, but the output is what I'm concerned about.

Homework Equations

The Attempt at a Solution



Code:
#include <stdio.h>
#include <stdlib.h>

void foo(int a, int b) {
  int r = a+b;
  a += 2;
  printf("(AR1) r = %d, a = %d \n", r, a);
}

void foo2(int *a, int *b){
  *a = (*a)*2;
  b = a;
  printf("(AR2) *a = %d, *b = %d \n", *a, *b);
}

int main() {
  int x = 5, y = 2;
  int *p = &x, *r = &y;
  printf("(AR3) x = %d, y = %d, *p = %d, *r = %d \n", x, y, *p, *r);
   
  foo(x,y);
  printf("(AR4) x = %d, y = %d, *p = %d, *r = %d \n", x, y, *p, *r);

  foo2(p,r);
  printf("(AR5) x = %d, y = %d, *p = %d, *r = %d \n", x, y, *p, *r);

  r++;
  printf("(AR6) x = %d, y = %d, *p = %d, *r = %d \n", x, y, *p, *r);
   
  return 0;
}

This produces the following output:

Code:
(AR3) x = 5, y = 2, *p = 5, *r = 2
(AR1) r = 7, a = 7
(AR4) x = 5, y = 2, *p = 5, *r = 2
(AR2) *a = 10, *b = 10
(AR5) x = 10, y = 2, *p = 10, *r = 2
(AR6) x = 10, y = 2, *p = 10, *r = 10

Activation record 6 is of some interest. For some reason, when ##r++## is read, the pointer ##r## decides to point to the same value ##p## is pointing to (which is ##x = 10##).

Why does this happen?

Executing ##r++## again interestingly made ##r## point to zero.
 
Physics news on Phys.org
'r' is of type 'pointer to int', i.e. it stores a memory address. When you execute 'r++', you're doing pointer arithmetic - you're increasing the memory address stored in 'r' by sizeof(int). That so happens to be the address of 'x'.
 
As a sidenote: If you want to know why incrementing 'r' makes it point to 'x', you should look up how variables are allocated on the stack and how that's typically organized in memory for your platform.
 
There's a phrase that's useful to memorize:
Pointer arithmetic is scaled by the type of object that is pointed to.
Assuming that ptr is a pointer variable, then the expressions ptr + 1 and ptr++ will have different values depending on how ptr is declared.

If ptr is of type char *, then ptr + 1 and ptr++ both contain the address of the next byte in memory (assuming a char is a single byte).
If ptr is of type int *, then ptr + 1 and ptr++ both contain the address of the next int in memory, which likely will be four bytes higher in memory, assuming an int is four bytes.

Pointer decementing and subtracting an int value from a pointer variable work in a similar way.
 
Mark44 said:
If ptr is of type int *, then ptr + 1 and ptr++ both contain the address of the next int in memory, which likely will be four bytes higher in memory, assuming an int is four bytes.

Thank you for making that apparent. So if I have n ints (not in an array) then ptr++ will point to the next integer (likely sizeof(int) higher in memory). I found that weird and counter-intuitive.

Usually we use a pointer to the address of the zero'ith element in an array (&arr[0] == arr). Makes more sense to do it that way anyway.
 
Zondrina said:
So if I have n ints (not in an array) then ptr++ will point to the next integer (likely sizeof(int) higher in memory).
You have no guarantee of this. Arrays in C are contiguous in the (virtual) memory space of your application, but variables with local scope, like your 'x', can be allocated however your compiler sees fit. 'ptr++' might point to garbage or perhaps even a virtual memory page that has no physical mapping yet, which will you give you a run-time error when you try to access it.

With that said, it's typical for most C compilers to allocate local variables, in order of appearance, in a LIFO structure in low memory (the stack), which grows "downwards" in memory from high to low memory addresses. Assuming a 4-byte int, the stack frame for 'main' in your application might look like this:

Address, Symbol
00000000, 'r'
00000004, 'p'
00000008, 'y'
0000000C, 'x'

So 'r' and 'r++' contain 0x8 and 0xC, respectively.
 
milesyoung said:
You have no guarantee of this. Arrays in C are contiguous in the (virtual) memory space of your application, but variables with local scope, like your 'x', can be allocated however your compiler sees fit. 'ptr++' might point to garbage or perhaps even a virtual memory page that has no physical mapping yet, which will you give you a run-time error when you try to access it.

With that said, it's typical for most C compilers to allocate local variables, in order of appearance, in a LIFO structure in low memory (the stack), which grows "downwards" in memory from high to low memory addresses. Assuming a 4-byte int, the stack frame for 'main' in your application might look like this:

Address, Symbol
00000000, 'r'
00000004, 'p'
00000008, 'y'
0000000C, 'x'

So 'r' and 'r++' contain 0x8 and 0xC, respectively.

I wonder why C99 does this; p++ could point you to the next address of a local variable, or it could go boom and point essentially nowhere. Pointer arithmetic on anything except array names seems to be tacky.
 
Zondrina said:
I wonder why C99 does this; p++ could point you to the next address of a local variable, or it could go boom and point essentially nowhere. Pointer arithmetic on anything except array names seems to be tacky.

It's 'tacky' when abused but when used in the right context (operating systems,embedded design,etc..) it's elegant.
http://www.cs.umd.edu/class/sum2003/cmsc311/Notes/BitOp/pointer.html
 
Zondrina said:
I wonder why C99 does this; p++ could point you to the next address of a local variable, or it could go boom and point essentially nowhere. Pointer arithmetic on anything except array names seems to be tacky.
I would agree with nsaspook here. When working "close to the metal" with resource-limited systems, it's very useful to be able to index directly into the address space.

However, it's certainly no secret that C allows you ample freedom in setting up a shot to the foot.
 
  • #10
From the perspective of a developer who is writing applications, there's not much reason for you to use pointer arithmetic (such as incrementing a pointer) for memory that doesn't belong to an array.

From the perspective of someone writing operating system code, which was main reason C was created, there are good reasons, as nsaspook and milesyoung have already mentioned.
 

Similar threads

  • · Replies 17 ·
Replies
17
Views
3K
  • · Replies 3 ·
Replies
3
Views
1K
  • · Replies 19 ·
Replies
19
Views
3K
  • · Replies 3 ·
Replies
3
Views
1K
  • · Replies 3 ·
Replies
3
Views
3K
  • · Replies 2 ·
Replies
2
Views
2K
  • · Replies 6 ·
Replies
6
Views
2K
  • · Replies 1 ·
Replies
1
Views
1K
  • · Replies 8 ·
Replies
8
Views
2K
  • · Replies 5 ·
Replies
5
Views
3K