Pointers The Pointer Defined int *x; Read as: declare x as a - - PowerPoint PPT Presentation

pointers the pointer defined
SMART_READER_LITE
LIVE PREVIEW

Pointers The Pointer Defined int *x; Read as: declare x as a - - PowerPoint PPT Presentation

Pointers The Pointer Defined int *x; Read as: declare x as a pointer to a 32-bit integer Interpretation: declare x as a variable on the stack that holds the numeric address of the location in memory at which are 32 bits that we intend


slide-1
SLIDE 1

Pointers

slide-2
SLIDE 2

The Pointer Defined

  • int *x;
  • Read as: declare x as a pointer to a 32-bit integer
  • Interpretation: declare x as a variable on the stack that holds the

numeric address of the location in memory at which are 32 bits that we intend to manipulate as a signed integer

  • sizeof(x) is the word-size of the machine in bytes
  • on a 32 bit machine that can address 2^32 bytes of memory, 4
  • on a 64 bit machine, 8
  • etc
  • sizeof(*x) is 4, or sizeof(int)
slide-3
SLIDE 3

Pointer Dereferencing

  • There are two fundamental ways to manipulate or obtain

(dereference) memory through this pointer:

  • *x
  • Read as: dereference x
  • Interpretation: set(if left of equals) or get(if right of equals) 32 bits of

memory interpreted as a signed integer beginning at the memory address contained in variable x

slide-4
SLIDE 4

Pointer Dereferencing Continued

  • x[i]
  • Read as: the (i + 1)st element of array x (indices start at 0)
  • Interpretation: set or get 32 bits of memory interpreted as a signed

integer beginning at the memory address computed as address + (i * sizeof(type))

  • For all examples that follow, assume x contains the value 10000, i.e.

x refers to the 10000th byte of memory

  • x[5] will manipulate or obtain the 32 bit signed integer beginning at

address (10000 + (5 * 4)), or 10020

slide-5
SLIDE 5

Arrays Versus Pointers

  • int x[256];
  • This is a declaration of 256 contiguous 4-byte integers on the stack (1024 bytes total)
  • The identifier x is a pointer to an integer that points to this stack location, and it can never point anywhere

else

  • int *x;
  • This is a declaration of a pointer to an integer that does not refer to any location until it is assigned a value (for

example using the & operator or via malloc)

  • It can point to any address in memory, stack or heap, and its value can be changed dynamically
  • RHS use of either identifier x operates almost identically; use either as a pointer to one-to-many

integers, or deference either to obtain an single integer

  • Can’t put the array-char-pointer on the LHS (i.e. can’t say x = something, but can say

x[index] = something) (this makes sense if you think about it)

  • Compiler generates instructions to compute the exact stack-pointer-relative address for any

chosen element of the array when using an array; it can do this because it knows it’s contiguous

  • Compiler generates instructions to compute the pointer-value-relative address for any chosen

element of the array when using a pointer

slide-6
SLIDE 6

Array Storage

10000 10004 10008 10012 10016 10020 10024 10028 10032 10036 10040 int *x; 10000 1st 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 1 2 3 4 5 6 7 8 9 10 11 10044 100 x[5]=100;

slide-7
SLIDE 7

Implications of the Pointer-type

  • The CPU *does not* make any assumptions about how to interpret

any piece of memory, you must explicitly tell it how to do so

  • The compiler does all pointer arithmetic using the guidance you gave

it via the type you declared that the pointer points to

  • The compiler chooses machine instructions to generate for the CPU

based upon the type you declared that the pointer points to

slide-8
SLIDE 8

Implications of the Pointer-Type continued

  • Previous example demonstrated operations on 4 byte values and pointer

arithmetic by 4-byte values because an int is represented as 4 bytes

  • If x were declared as: char *x;
  • Operations on 1 byte signed integers
  • *x refers to address 10000
  • x[5] refers to address 10005
  • If x were declared as: short *x;
  • Operations on 2 byte signed integers
  • *x refers to address 10000
  • x[5] refers to address 10010
  • If x were declared as unsigned long long *x;
  • Operations on 8 byte unsigned integers
  • *x refers to address 10000
  • x[5] refers to address 10040
slide-9
SLIDE 9

Pointer Manipulation

  • C allows you to “add-to” or “subtract-from” a pointer by using

mathematical operators + and –

  • C doesn’t add the addend to the address directly, but performs the

following computation:

  • address = address + (addend * sizeof(type))
  • Interpretation: when you add one to a pointer, it causes the pointer to

point to the address of the next contiguous piece of memory of sizeof(type)

  • Semantic equivalent: were x pointing to the ith element of an array in

memory, it’s the equivalent of setting x to point to the (i+1)st element

  • As discussed, dereferencing an array causes a comparable computation:
  • &x[i] = x + (i * sizeof(type)
slide-10
SLIDE 10

Pointers to Pointers

  • int **x;
  • Read as: declare x as a pointer to a pointer to a 32-bit integer
  • Interpretation: declare x as a variable on the stack that holds the

numeric address at which is another numeric address at which are 32 bits that we intend to manipulate as a signed integer

  • sizeof(x) is the word size of the machine in bytes
  • sizeof(*x) is also the word size of the machine (it’s an int*)
  • sizeof(**x) is 4, or sizeof(int)
slide-11
SLIDE 11

Multi-Dimensional Arrays Versus Pointers

  • int x[256][10];
  • This is a declaration of a contiguous pool of stack memory that we intend to interpret as 256 “rows” of 10 “columns”, each

holding a 4-byte integer for a total of 256*10*4 = 10240 bytes of memory.

  • The identifier x is a pointer to a pointer to an integer that points to the beginning of this pool on the stack, and it can never

point anywhere else

  • int **x;
  • This is a declaration of a pointer to a pointer to an integer that does not refer to any location until it is assigned a value (for

example using the & operator or via malloc)

  • It can point to any address in memory, stack or heap, and its value can be changed dynamically
  • RHS use of either identifier x operates almost identically; use either as a pointer to pointer to one-to-many

integers, or deference either twice to obtain an single integer

  • Can’t put the array-char-p2p on the LHS (i.e. can’t say x = something, but can say x[index] =

something)

  • Compiler generates instructions to compute the exact stack-pointer-relative address for any chosen element
  • f the array when using an array; it can do this because it knows it’s contiguous
  • Compiler generates instructions to compute the pointer-value-relative addresses for any chosen element of

the array when using a pointer

slide-12
SLIDE 12

Stack-Based Multi-Dimensional Array Storage

int x[4][6]; 10000 10000 10004 10008 10012 10016 10020 10024 10048 10072

7th 8th 9th 10th 11th 12th 1st 2nd 3rd 4th 5th 6th 13th 14th 15th 16th 17th 18th 19th 20th 21st 22nd 23rd 24th 1 2 3 4 5

x[3][2] = 100; 100

Allocated & deallocated automatically via stack advancement & retreat Total storage of a 3x5 array of integers is (3x5) * 4

slide-13
SLIDE 13

Heap-Based Multi-Dimensional Array Storage

Must be allocated iteratively via malloc Must be freed iteratively via free Total storage of a 3x5 array of integers is (3x(5+1)) * 4

10000 10004 10008 10012 10016 10020 10024 10028 10032 10036 10040 int **x; 10000 1st 2nd 3rd 4th 5th 6th 7th 8th 9th 10th 11th 1 2 3 4 5 6 7 8 9 10 11 10044 100000 100004 100008 100012 100016 100020 1st 2nd 3rd 4th 5th 1 2 3 4 5 100000 int *x; 100 x[5][2] = 100

slide-14
SLIDE 14

Pointer Casting

  • int i = 5;
  • char *y = (char *)(&i);
  • Declares i as an integer on the stack and puts 5 in that location, then

declares y as a pointer to a character and assigns the address of i casted (interpreted as) to a pointer to a character to it.

  • &i and y both have the same numeric value pointing to the same

piece of memory

  • Dereferencing y hereafter generates instructions that operate on

chars at i’s memory address instead of integers

slide-15
SLIDE 15

Pointer Casting Example

enum integral_type { ITYPE_CHAR = 0, ITYPE_SHORT, ITYPE_INT, ITYPE_LONGLONG }; void doublevalue(void *pointer_to_integral_type, enum integral_type data_type) { if(pointer_to_integral_type == NULL) return; switch(data_type) { case ITYPE_CHAR: // doubles the 8-bit value found at pointer *((char *)pointer_to_integral_type) *= 2; break;

case ITYPE_SHORT: // doubles the 16 bit value found at pointer *((short *)pointer_to_integral_type) *= 2; break; case ITYPE_INT: // doubles the 32 bit value found at pointer *((int *)pointer_to_integral_type) *= 2; break; case ITYPE_LONGLONG: // doubles the 64 bit value found at pointer *((long long *)pointer_to_integral_type) *= 2; break; default: return; } }