muchen 牧辰


Updated 2017-10-24

Note: readers are assumed to have basic C programming knowledge (e.g., from APSC 160).



int * a; // a pointer to integer (4 bytes / 32 bits)
char * b; // a pointer to char (1 byte / 8 bits)

Generic Pointer

Generic pointer just points to a location in memory, but it does not know how long the memory to read, so they need to be casted before they can be dereferenced

int x = 10;
char ch = 'A';
void * generic_pointer; // cannot use this without casting

// retrieve content of pointer
gp = &x;
printf("integer value: %d":, (int*)gp); // casting when using

/* if the pointer is casted wrong, it will read incorrect length of memory
 * ex. a pointer for integer casted as char will only read the first byte

Pointer to another pointer

int x = 5;
int *p = &x;

*p = 6;
int ** q = &p;
int *** r = &q;

printf("%d\n", *p); // >>> 6
printf("%d\n", *q); // >>> 0x000aef4 (memory address)
printf("%d\n", **q); // >>> 6

printf("%d\n", **q); // >>> memory address of 'p'

Stack - Pointers in Parameters

Passing by value

subject function is abstracted - we only care about the input and output. A “copy” of the original parameter is created

void foo(int a) {
  // parameter 'a' gets new allocated memory, value is copied to new memory
  // actions performed on the new instance of memory

void main() {
  // allocate new memory for 'a'
  int a = 5;

Computers usually assign a “stack” of memory for the function to use temporarily. The computer will try its best to grow as function requires more memory. If the stack can’t grow any further: stack overflow

####Passing by Reference

void foo(int* a) {
  /* new memory allocated for the POINTER for 'a', makes the memory usage
   * much smaller as pointers only use up 1 byte computer to 4 bytes for
   * integers

  // incrementing the actual memory (initiated back in 'main()')

void main() {
  // new memory created for 'a'
  int a = 10;


The stack is cleared when the function ends, so the pointer in “main()” that points to the variable in the foo function will get garbage value

int foo(int* a) {
  int b = a++;
  return &b; // <---- this will not work (unsafe)

void main() {
  int a = 10;
  int* c = foo(&a);
  printf("%d", *c) // <---- this will not work (unsafe)

Heap - Dynamic Memory Allocation

When we don’t know how big the memory should be to account for the required data. (ex. unknown size of an array)

Memory Management


int square(int x) {
  return x*x;

  // these x in the stack of memory is cleared off when the function is finished

int squareOfSum(int x, int y) {
  return square(x+y);

int main() {
  int a = 4;
  int b = 8;
  int total = squareOfSum(a, b);
  printf("%d", total);

  // the whole program will be cleared off memory after program is done

So in the stack we have:

int x
int x, y
int a, b

Dynamic Memory Allocation

ptr = (<cast-type>*)malloc(<byte-size>)
ptr = (<cast-type>*)calloc(<byte-size>)

Heap Example

Instead of passing random size, we can use sizeof to specify the actual need size of the memory pointer

int main() {
  // goes on stack
  int a;

  // goes in the heap
  int* p = (int*)malloc(sizeof(int))

If there is no memory left on the heap, malloc will return a null pointer

int main() {
  // multiple the malloc param to access more memory (for arrays)
  int n =  100;
  int* p (int*)malloc(n*sizeof(int))

Pointer Arithmetic

// when we reference 'A', we get address to the beginning
// of the memory block that stores 'A'
int A[5];
A = {3, 5, 8, 13, 21};

// this is a pointer that points to the beginning of the
// memory block for 'A' as well
int* q = &A[0];
printf("%d\n", *q); // >>> 3 (first element in the array)

// (q+1) asks for the next integer (or any type)
printf("%d\n", *(q+1)); // >>> 5 (second element in the array)

Addresses and Call by Reference

Memory and Pointer Mistakes

Memory Leak

Dangling Pointer

Segment Faults