4

I am in the process of learning C, and have begun exploring the world of pointers and pointer arithmetic. For example, in the following code snippet:

int nums[] = {1, 2, 3};

nums is an Array variable and acts like a pointer that points to the first memory location of the array. I wrote the following sample code and am trying to understand why I am getting the results that I am getting:

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

int main() 
{
  int nums[] = {1, 2, 3};

  if(nums == &nums)
    puts("nums == &nums");
  else
    puts("nums != &nums");

  if((nums + 1) == (&nums + 1))
    puts("(nums + 1) == (&nums + 1)");
  else
    puts("(nums + 1) != (&nums + 1)");    

  printf("nums: %i\n", nums);
  printf("&nums: %i\n", &nums);
  printf("nums + 1: %i\n", nums + 1);
  printf("&nums + 1: %i\n", &nums + 1);

  return 0;    
}

I am getting that nums == &nums is true as expected; however, when I apply pointer arithmetic and add 1 to nums this result does not equal &nums + 1. In other words (nums + 1) != (&nums + 1) even though nums == &nums.

This is the output of the program that I get:

nums == &nums
(nums + 1) != (&nums + 1)
nums: 2345600
&nums: 2345600
nums + 1: 2345604
&nums + 1: 2345612

It appears that nums and nums + 1 are off set by 4 bytes; however, &nums and &nums + 1 are offset by 12. Why is it that this offset is by 12 bytes and not by 4?

2
  • By the way, you might want to consider using %p to printf pointer values. Commented Aug 19, 2015 at 18:02
  • 1
    possible duplicate of So you think you know pointers? Commented Aug 19, 2015 at 18:03

2 Answers 2

7

The confusion is related to how in C, arrays implicitly decay into pointers in certain contexts.

The easier one to explain, nums + 1 effectively means &nums[0] + 1. nums[0] is type int, which is 4 bytes per element. Thus &nums[0] + 1 is 4 bytes after &nums.

As for &nums + 1, &nums is of type int(*)[3], which is 12 bytes per element. Thus &nums + 1 is 12 bytes after &nums.

Sign up to request clarification or add additional context in comments.

2 Comments

Interesting, this would mean that if I wanted to get the next memory location directly after the array I could use "&nums + 1". Thanks for the quick answer.
Yes, that's true. However you cannot actually use that memory location, because it would invoke undefined behavior. Nor are you allowed to compute any memory locations past the end, either.
2

Both expressions, (int*) nums and &nums have pointer types, but the types pointed to are different. You only can test them for equality in C, not C++.

The type of nums is int[3], that is, 'array of 3 objects of type int' and the type of (int*) nums is int*, that is, 'a pointer to int' . Adding 1 to (int*) nums means obtaining a pointer to an object of type int that follows nums[0]. In terms of addresses that means adding 1 * sizeof (int).

The type of &nums is int(*)[3], that is, 'pointer to an array of 3 objects of type int'. Adding 1 to &nums means obtaining a pointer to an object of type int[3] that follows nums. In terms of addresses that means adding 1 * sizeof (int[3]), that is, 3 * sizeof (int).

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.