Weird Pointer Outcome: Analyzing Activation Record 6

  • Thread starter STEMucator
  • Start date
  • Tags
    Weird
In summary, the conversation discusses the behavior of pointer arithmetic in C, specifically the use of the increment operator on a pointer variable. It is explained that pointer arithmetic is scaled by the type of object being pointed to, and the behavior of pointer incrementing is dependent on the way variables are allocated on the stack. It is also noted that while pointer arithmetic can be useful in certain contexts, it can also lead to errors if used improperly.
  • #1
STEMucator
Homework Helper
2,076
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
  • #2
'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'.
 
  • #3
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.
 
  • #4
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.
 
  • #5
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.
 
  • #6
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.
 
  • #7
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.
 
  • #8
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
 
  • #9
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.
 

1. What is a "Weird Pointer Outcome"?

A "Weird Pointer Outcome" is a term used in computer programming to describe a situation where a pointer (a variable that stores the memory address of another variable) points to an unexpected or unintended location in the computer's memory. This can result in unexpected program behavior or errors.

2. What is an Activation Record?

An Activation Record, also known as a stack frame, is a data structure used by computer programs to store information about a specific function call. It contains information such as the function's parameters, local variables, and the return address. It is created and destroyed as a function is called and returns.

3. What does it mean to "Analyze Activation Record 6"?

Analyzing Activation Record 6 refers to examining the sixth activation record on the stack at a specific point in a program's execution. This can provide insight into the state of the program and help identify potential issues, such as a weird pointer outcome.

4. How can a weird pointer outcome be caused by Activation Record 6?

A weird pointer outcome can be caused by Activation Record 6 if the pointer stored in that record is pointing to an unexpected or unintended location in the computer's memory. This can happen if the pointer was not properly initialized or if the memory it points to has been modified by another part of the program.

5. How can I fix a weird pointer outcome caused by Activation Record 6?

To fix a weird pointer outcome caused by Activation Record 6, you will need to identify and correct the root cause of the issue. This may involve debugging your code and ensuring that all pointers are properly initialized and pointing to the correct memory locations. You may also need to carefully manage memory usage and prevent any unwanted modifications to the memory.

Similar threads

  • Engineering and Comp Sci Homework Help
Replies
17
Views
1K
  • Engineering and Comp Sci Homework Help
Replies
3
Views
668
  • Engineering and Comp Sci Homework Help
Replies
3
Views
754
  • Engineering and Comp Sci Homework Help
Replies
19
Views
2K
  • Engineering and Comp Sci Homework Help
Replies
3
Views
1K
  • Engineering and Comp Sci Homework Help
Replies
6
Views
854
  • Engineering and Comp Sci Homework Help
Replies
2
Views
1K
  • Engineering and Comp Sci Homework Help
Replies
5
Views
2K
  • Engineering and Comp Sci Homework Help
Replies
8
Views
2K
  • Engineering and Comp Sci Homework Help
Replies
1
Views
762
Back
Top