Skip to content

Instantly share code, notes, and snippets.

@chmullig
Last active December 14, 2015 02:38
Show Gist options
  • Save chmullig/5014565 to your computer and use it in GitHub Desktop.
Save chmullig/5014565 to your computer and use it in GitHub Desktop.
A little pointer program to help show exactly how pointer functions work.
CC = gcc
CFLAGS = -Wall -g
LDFAGS = -g
pointerfun:
pointerfun_clang: pointerfun.c
clang $(CFLAGS) $(LDFLAGS) -o pointerfun_clang pointerfun.c
pointerfun.o:
output: pointerfun
./pointerfun > output
.PHONY: clean all valgrind
clean:
rm -f *.o pointerfun
all: clean pointerfun pointerfun_clang
valgrind: pointerfun
valgrind --leak-check=yes ./pointerfun
We'll be running a series of experiments, and printing the results
to try to better understand pointers and memory in C. Ready?
The memory address of global variable globalvar is 0x602050
The memory address of static variable staticvar is 0x602058
The memory address of local variable a is 0x7fff36c22ad4
The memory address of local variable b is 0x7fff36c22ad8
ptr_to_a has the address 0x7fff36c22a98, and the content 0x7fff36c22ad4. *ptr_to_a = 4
ptr_to_ptr_to_a has the address 0x7fff36c22aa0, and the content 0x7fff36c22a98. *ptr_to_ptr_to_a = 0x7fff36c22ad4. **ptr_to_ptr_to_a = 4
Mallocing *c to sizeof(int)*5; *d to sizeof(int)
The memory address on the heap int *c points to is 0x17c6010
The memory address on the heap int *d points to is 0x17c6030
But note that c itself is in the address 0x7fff36c22aa8. 0x7fff36c22aa8 -> 0x17c6010, which contains 9
Look at all the different ways we can use pointers to a block of malloc'd memory
Now looping through c+0...c+4:
*(c+0) == 9 c[0] == 9 0[c] == 9
*(c+1) == 10 c[1] == 10 1[c] == 10
*(c+2) == 11 c[2] == 11 2[c] == 11
*(c+3) == 12 c[3] == 12 3[c] == 12
*(c+4) == 0 c[4] == 0 4[c] == 0
e = NULL. Its value is (nil)
e = 0. Its value is still (nil)
e = '\0'. Its value is still (nil)
Now let's play with functions!
The memory address of the function add is 0x400a7e
The memory address of the function multiply is 0x400ac7
We'll try to add, by asking the operate function to use the add function...
We'll add a + b and store into d
(inside operate) Storing into 0x17c6030 results of operation at memory address 0x400a7e
(inside add) Adding the contents of 0x7fff36c22ad4 and 0x7fff36c22ad8. (4+3)
The contents of malloc'd space 0x17c6030, d, is 7
Ok, now let's try to multiply, by asking the operate function to use the multiply function...
We'll multiply a * b and store into globalvar
(inside operate) Storing into 0x602050 results of operation at memory address 0x400ac7
(inside multiply) Multiplying the contents of 0x7fff36c22ad4 and 0x7fff36c22ad8. (4*3)
The contents of global variable 0x602050, globalvar, is 12
"This is a string literal!" is acessed via char *sl at 0x401270
The last character of ^ is '!', stored at 0x401288
/**
* Chris Mulligan, clm2186
* COMSW3157 Advanced Programming
* pointerfun.c
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int add(const int *a, const int *b);
int multiply(const int *a, const int *b);
void operate(const int *a, const int *b, int *dest, int (*operationPtr)(const int *, const int*));
int globalvar = 0;
int main(int argc, char **argv) {
printf("We'll be running a series of experiments, and printing the results\n"
"to try to better understand pointers and memory in C. Ready?\n\n");
static double staticvar = 0.0;
printf("The memory address of global variable globalvar is %p\n", &globalvar);
printf("The memory address of static variable staticvar is %p\n", &staticvar);
printf("\n");
int a = 4;
int b = 3;
printf("The memory address of local variable a is %p\n", &a);
printf("The memory address of local variable b is %p\n\b", &b);
int *ptr_to_a;
ptr_to_a = &a;
printf("ptr_to_a has the address %p, and the content %p. *ptr_to_a = %d \n\n",
&ptr_to_a, ptr_to_a, *ptr_to_a);
int **ptr_to_ptr_to_a;
ptr_to_ptr_to_a = &ptr_to_a;
printf("ptr_to_ptr_to_a has the address %p, and the content %p. "
"*ptr_to_ptr_to_a = %p. **ptr_to_ptr_to_a = %d \n\n",
&ptr_to_ptr_to_a, ptr_to_ptr_to_a, *ptr_to_ptr_to_a, **ptr_to_ptr_to_a);
printf("Mallocing *c to sizeof(int)*5; *d to sizeof(int)\n");
int *c = malloc(sizeof(int)*5);
int *d = malloc(sizeof(int));
*c = 9;
printf("The memory address on the heap int *c points to is %p\n", c);
printf("The memory address on the heap int *d points to is %p\n", d);
printf("\tBut note that c itself is in the address %p.", &c);
printf("\t%p -> %p, which contains %d \n", &c, c, *c);
printf("Look at all the different ways we can use pointers to a block of malloc'd memory\n");
*(c+1) = 10;
c[2] = 11;
3[c] = 12;
*(c+4) = 0;
printf("Now looping through c+0...c+4:\n");
int i;
for (i = 0; i < 5; i++) {
printf(" *(c+%d) == %2d", i, *(c+i));
printf(" c[%d] == %2d", i, c[i]);
printf(" %d[c] == %2d \n", i, i[c]);
}
printf("\n");
int *e;
e = NULL;
printf("e = NULL. Its value is %p\n", e);
e = 0;
printf("e = 0. Its value is still %p\n", e);
e = '\0';
printf("e = '\\0'. Its value is still %p\n", e);
printf("\n");
printf("Now let's play with functions!\n");
printf("The memory address of the function add is %p\n", &add);
printf("The memory address of the function multiply is %p\n", &multiply);
printf("\n");
printf("We'll try to add, by asking the operate function to use the add function...\n");
printf("We'll add a + b and store into d \n");
operate(&a, &b, d, &add);
printf("The contents of malloc'd space %p, d, is %d\n", d, *d);
printf("\n");
printf("Ok, now let's try to multiply, by asking the operate function to use the multiply function...\n");
printf("We'll multiply a * b and store into globalvar \n");
operate(&a, &b, &globalvar, &multiply);
printf("The contents of global variable %p, globalvar, is %d\n", &globalvar, globalvar);
/* allways free! */
free(c);
free(d);
printf("\n\n");
char *sl = "This is a string literal!";
printf("\"%s\" is acessed via char *sl at %p\n", sl, sl);
char *lastChar = sl+strlen(sl)-1;
printf("The last character of ^ is '%c', stored at %p\n", *lastChar, lastChar);
return 0;
}
/* add two ints, returning the sum */
int add(const int *a, const int *b) {
printf(" (inside add) Adding the contents of %p and %p. (%d+%d)\n", a, b, *a, *b);
return *a + *b;
}
/* Multiple two ints, returning the product */
int multiply(const int *a, const int *b) {
printf(" (inside multiply) Multiplying the contents of %p and %p. (%d*%d)\n", a, b, *a, *b);
return *a * *b;
}
/* Call a function on two pointers, store the result to another location */
void operate(const int *a, const int *b, int *dest, int (*operationPtr)(const int *, const int*)) {
printf(" (inside operate) Storing into %p results of operation at memory address %p\n", dest, operationPtr);
*dest = (*operationPtr)(a, b);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment