CMPSC 311- Introduction to Systems Programming Module: Variables - - PowerPoint PPT Presentation

cmpsc 311 introduction to systems programming module
SMART_READER_LITE
LIVE PREVIEW

CMPSC 311- Introduction to Systems Programming Module: Variables - - PowerPoint PPT Presentation

CMPSC 311- Introduction to Systems Programming Module: Variables Arrays and Pointers Professor Patrick McDaniel Fall 2016 CMPSC 311 - Introduction to Systems Programming Variable Storage Classes C (and other languages) have several


slide-1
SLIDE 1

CMPSC 311 - Introduction to Systems Programming

CMPSC 311- Introduction to Systems Programming Module: Variables Arrays and Pointers

Professor Patrick McDaniel Fall 2016

slide-2
SLIDE 2

CMPSC 311 - Introduction to Systems Programming Page

Variable Storage Classes

  • C (and other languages) have several storage that are

defined by their scope

  • auto – these are automatically allocated and deallocated

variables (local function variables declared on stack)

  • global – globally defined variables that can be accessed

anywhere within the program

  • extern is used in .c/.h files to indicate a variable defined

elsewhere

  • static – a variable that is global to the local file only
  • Static is used identify variable as local only

static int localScopeVariable; // Static variable extern int GlobalVariable; // Global variable defined elsewhere

slide-3
SLIDE 3

CMPSC 311 - Introduction to Systems Programming Page

Rules for initialization

  • In general, static or global variables are giving a default

value and auto are indeterminate

  • meaning that the compiler can do anything it wants, which for

most compilers is take whatever value is in memory

  • You cannot depend on indeterminate values

C89 Specification : If an object that has automatic storage duration is not initialized explicitly, its value is indeterminate. If an object that has static storage duration is not initialized explicitly, it is initialized implicitly as if every member that has arithmetic type were assigned 0 and every member that has pointer type were assigned a null pointer constant. C99 Specification : If an object that has automatic storage duration is not initialized explicitly, its value is indeterminate. If an object that has static storage duration is not initialized explicitly, then: — if it has pointer type, it is initialized to a null pointer; — if it has arithmetic type, it is initialized to (positive or unsigned) zero; — if it is an aggregate, every member is initialized (recursively) according to these rules; — if it is a union, the first named member is initialized (recursively) according to these rules.

slide-4
SLIDE 4

CMPSC 311 - Introduction to Systems Programming Page

Arrays

  • type name[size];
  • example allocates 100 ints worth of memory
  • initially, each array element contains garbage data
  • an array does not know its own size
  • sizeof(scores) is not reliable; only works in some situations
  • recent versions of C allow the array size to be an expression

4

int scores[100]; int n=100; int scores[n]; // OK in C99

C Arrays are zero indexed!

slide-5
SLIDE 5

CMPSC 311 - Introduction to Systems Programming Page

Initializing and using arrays

  • type name[size] = {value, value, ..., value};
  • allocates and array and fills it with supplied values
  • if fewer values are given than the array size, fills rest with 0
  • name[index] = expression;
  • sets the value of an array element

5

int primes[6] = {2, 3, 5, 6, 11, 13}; primes[3] = 7; primes[100] = 0; // smash! // 1000 zeroes int allZeroes[1000] = {0};

slide-6
SLIDE 6

CMPSC 311 - Introduction to Systems Programming Page

Setting array values (cont.)

6

int val[3] = { 5, 5, 5 }; printf( "val [%d, %d, %d]\n", val[0], val[1], val[2] ); int val1[3] = { 0 }; printf( "val1 [%d, %d, %d]\n", val1[0], val1[1], val1[2] ); int val2[3] = { 1 }; printf( "val2 [%d, %d, %d]\n", val2[0], val2[1], val2[2] ); int val3[3] = {}; printf( "val3 [%d, %d, %d]\n", val3[0], val3[1], val3[2] ); int val4[3] = { [0 ... 2] = 1 }; printf( "val4 [%d, %d, %d]\n", val4[0], val4[1], val4[2] ); val [5, 5, 5] val1 [0, 0, 0] val2 [1, 0, 0] val3 [0, 0, 0] val4 [1, 1, 1]

slide-7
SLIDE 7

CMPSC 311 - Introduction to Systems Programming Page

Setting array values (cont.)

7

int val[3] = { 5, 5, 5 }; printf( "val [%d, %d, %d]\n", val[0], val[1], val[2] ); int val1[3] = { 0 }; printf( "val1 [%d, %d, %d]\n", val1[0], val1[1], val1[2] ); int val2[3] = { 1 }; printf( "val2 [%d, %d, %d]\n", val2[0], val2[1], val2[2] ); int val3[3] = {}; printf( "val3 [%d, %d, %d]\n", val3[0], val3[1], val3[2] ); int val4[3] = { [0 ... 2] = 1 }; printf( "val4 [%d, %d, %d]\n", val4[0], val4[1], val4[2] ); [5, 5, 5] [0, 0, 0] [1, 0, 0] [0, 0, 0] [1, 1, 1]

// Best approach to init all values int val4[3] = { [0 ... 2] = 1 };

slide-8
SLIDE 8

CMPSC 311 - Introduction to Systems Programming Page

Setting array values (cont.)

8

int val[3] = { 5, 5, 5 }; printf( "val [%d, %d, %d]\n", val[0], val[1], val[2] ); int val1[3] = { 0 }; printf( "val1 [%d, %d, %d]\n", val1[0], val1[1], val1[2] ); int val2[3] = { 1 }; printf( "val2 [%d, %d, %d]\n", val2[0], val2[1], val2[2] ); int val3[3] = {}; printf( "val3 [%d, %d, %d]\n", val3[0], val3[1], val3[2] ); int val4[3] = { [0 ... 2] = 1 }; printf( "val4 [%d, %d, %d]\n", val4[0], val4[1], val4[2] ); val [5, 5, 5] val1 [0, 0, 0] val2 [1, 0, 0] val3 [0, 0, 0] val4 [1, 1, 1]

slide-9
SLIDE 9

CMPSC 311 - Introduction to Systems Programming Page

Beware of the Internet ….

  • There is a lot misinformation, bad code, and bad advice
  • n the Internet (e.g., stackoverflow.com)
  • Don’t trust everything you read …

9

int inspect_stack(void) { char values[100] = { 1 }; printf("Values[0, 1, 2] = %d %d %d\n", values[0], values[1], values[2]); return(0); } Values[0, 1, 2] = 1 0 0

slide-10
SLIDE 10

CMPSC 311 - Introduction to Systems Programming Page

Multi-dimensional arrays

  • type name[rows][columns] = {{values}, ..., {values}};
  • allocates a 2D array and fills it with predefined values

10

// a 2 row, 3 column array of doubles double grid[2][3]; // a 3 row, 5 column array of ints int matrix[3][5] = { {0, 1, 2, 3, 4}, {0, 2, 4, 6, 8}, {1, 3, 5, 7, 9} }; grid[0][2] = (double) matrix[2][4]; // which val?

slide-11
SLIDE 11

CMPSC 311 - Introduction to Systems Programming Page

Arrays as parameters

  • It’s tricky to use arrays as parameters
  • arrays are effectively passed by reference (not copied)
  • arrays do not know their own size

11

int sumAll(int a[]); // prototype declaration int main(int argc, char **argv) { int numbers[5] = {3, 4, 1, 7, 4}; int sum = sumAll(numbers); return 0; } int sumAll(int a[]) { int i, sum = 0; for (i = 0; i < ...??? }

slide-12
SLIDE 12

CMPSC 311 - Introduction to Systems Programming Page

Arrays as parameters

  • Solution 1: declare the array size in the function
  • problem: code isn’t very flexible

12

int sumAll(int a[5]); // prototype declaration int main(int argc, char **argv) { int numbers[5] = {3, 4, 1, 7, 4}; int sum = sumAll(numbers); return 0; } int sumAll(int a[5]) { int i, sum = 0; for (i = 0; i < 5; i++) { sum += a[i]; } return sum; }

slide-13
SLIDE 13

CMPSC 311 - Introduction to Systems Programming Page

Arrays as parameters

  • Solution 1: declare the array size in the function
  • problem: code isn’t very flexible

13

int sumAll(int a[5]); // prototype declaration int main(int argc, char **argv) { int numbers[5] = {3, 4, 1, 7, 4}; int sum = sumAll(numbers); return 0; } int sumAll(int a[5]) { int i, sum = 0; for (i = 0; i < 5; i++) { sum += a[i]; } return sum; }

int sumAll(int a[5]) Note: the size is not enforced!

slide-14
SLIDE 14

CMPSC 311 - Introduction to Systems Programming Page

Arrays as parameters

  • Solution 2: pass the size as a parameter

14

int sumAll(int a[], int size); // Array passed by reference int main(int argc, char **argv) { int numbers[5] = {3, 4, 1, 7, 4}; int sum = sumAll(numbers, 5); printf("sum is: %d\n", sum); return 0; } int sumAll(int a[], int size) { int i, sum = 0; for (i = 0; i <= size; i++) { // CAN YOU SPOT THE BUG? sum += a[i]; } return sum; }

slide-15
SLIDE 15

CMPSC 311 - Introduction to Systems Programming Page

Returning an array

  • Local variables, including arrays, are stack allocated
  • they disappear when a function returns
  • therefore, local arrays can’t be safely returned from functions

15

int[] copyarray(int src[], int size) { int i, dst[size]; // OK in C99 for (i = 0; i < size; i++) { dst[i] = src[i]; } return dst; // NO -- bug }

slide-16
SLIDE 16

CMPSC 311 - Introduction to Systems Programming Page

Solution: an output parameter

  • Create the “returned” array in the caller
  • pass it as an output parameter to copyarray
  • works because arrays are effectively passed by reference

16

void copyarray(int src[], int dst[], int size) { int i; for (i = 0; i < size; i++) { dst[i] = src[i]; } }

slide-17
SLIDE 17

CMPSC 311 - Introduction to Systems Programming Page

OS and processes (redux)

  • The OS lets you run multiple applications at once
  • an application runs within an OS “process”
  • the OS timeslices each CPU between runnable processes
  • happens very fast; ~100 times per second!

17

  • • •

process N process 1 process 2

  • perating system
slide-18
SLIDE 18

CMPSC 311 - Introduction to Systems Programming Page

Processes and virtual memory

  • OS gives each process the illusion of its own, private

memory

  • called the process’ address space
  • contains the process’ virtual

memory, visible only to it

  • 32-bit pointers on 32- bit machine
  • 64-bit pointers on 64- bit machine

18

0x00000000 0xFFFFFFFF process’ address space

contains code, data, libraries, stack, etc.

slide-19
SLIDE 19

CMPSC 311 - Introduction to Systems Programming Page

Loading

  • When the OS loads a

program, it:

  • creates an address space
  • inspects the executable file

to see what’s in it

  • (lazily) copies regions of the

file into the right place in the address space

  • does any final linking,

relocation, or other needed preparation

19

0x00000000 0xFFFFFFFF

OS kernel [protected] stack shared libraries heap (malloc/free) read/write segment .data, .bss read-only segment .text, .rodata

slide-20
SLIDE 20

CMPSC 311 - Introduction to Systems Programming Page

Loading (regions)

20

0x00000000 0xFFFFFFFF

OS kernel [protected] stack shared libraries heap (malloc/free) read/write segment .data, .bss read-only segment .text, .rodata

Code Static Data Dynamic Data Code/Data for Libraries Process State/local variables

slide-21
SLIDE 21

CMPSC 311 - Introduction to Systems Programming Page

The stack in detail …

  • Used to store data associated

with function calls

  • when you call a function, compiler-

inserted code will allocate a stack frame to store:

  • the function call arguments
  • the address to return to
  • local variables used by the function
  • a few other pieces of bookkeeping

21

  • ffset

contents 4 8 12 16 20 24 a stack frame

int f(int p1, int p2) { int x; int a[3]; ... return x; }

x a[0] a[1] a[2] return address p1 p2

slide-22
SLIDE 22

CMPSC 311 - Introduction to Systems Programming Page

Stack example

22

#include <stdio.h> #include <stdint.h> int showstack( int i, int j ) { int k = 2; int32_t l[2]; printf( "i is at [%p], size [%lu], value [%d]\n", &i, sizeof(i), i ); printf( "j is at [%p], size [%lu], value [%d]\n", &j, sizeof(j), j ); printf( "k is at [%p], size [%lu], value [%d]\n", &k, sizeof(k), k ); printf( "l is at [%p], size [%lu], value [%d]\n", &l[1], sizeof(l[1]), l[1] ); return( 0 ); } int main( void ) { printf( "Hello world!\n" ); showstack( 3, 4 ); return( 0 ); }

slide-23
SLIDE 23

CMPSC 311 - Introduction to Systems Programming Page

Stack example

23

mcdaniel@ubuntu:~/tmp/helloworld$ make gcc showstack.c -o showstack mcdaniel@ubuntu:~/tmp/helloworld$ ./showstack Hello world! i is at [0x7fffe345f0ec], size [4], value [3] j is at [0x7fffe345f0e8], size [4], value [4] k is at [0x7fffe345f0fc], size [4], value [2] l is at [0x7fffe345f104], size [4], value [0] mcdaniel@ubuntu:~/tmp/helloworld$ ... int showstack( int i, int j ) { int k = 2; int32_t l[2]; ... int main( void ) { printf( "Hello world!\n" ); showstack( 3, 4 ); return( 0 ); }

slide-24
SLIDE 24

CMPSC 311 - Introduction to Systems Programming Page

The stack in action

24

int main(int argc, char **argv) { int n1 = f(3, -5); n1 = g(n1); } int f(int p1, int p2) { int x; int a[3]; ... x = g(a[2]); return x; } int g(int param) { return param * 2; }

OS kernel [protected] stack heap (malloc/free) read/write segment globals read-only segment (main, f, g) main

argc, argv, n1

slide-25
SLIDE 25

CMPSC 311 - Introduction to Systems Programming Page

The stack in action

25

int main(int argc, char **argv) { int n1 = f(3, -5); n1 = g(n1); } int f(int p1, int p2) { int x; int a[3]; ... x = g(a[2]); return x; } int g(int param) { return param * 2; }

OS kernel [protected] stack heap (malloc/free) read/write segment globals read-only segment (main, f, g) main

argc, argv, n1

slide-26
SLIDE 26

CMPSC 311 - Introduction to Systems Programming Page

The stack in action

26

int main(int argc, char **argv) { int n1 = f(3, -5); n1 = g(n1); } int f(int p1, int p2) { int x; int a[3]; ... x = g(a[2]); return x; } int g(int param) { return param * 2; }

OS kernel [protected] stack heap (malloc/free) read/write segment globals read-only segment (main, f, g) main

argc, argv, n1

slide-27
SLIDE 27

CMPSC 311 - Introduction to Systems Programming Page

The stack in action

27

int main(int argc, char **argv) { int n1 = f(3, -5); n1 = g(n1); } int f(int p1, int p2) { int x; int a[3]; ... x = g(a[2]); return x; } int g(int param) { return param * 2; }

OS kernel [protected] stack heap (malloc/free) read/write segment globals read-only segment (main, f, g) main

argc, argv, n1 f p1, p2, x, a

slide-28
SLIDE 28

CMPSC 311 - Introduction to Systems Programming Page

The stack in action

28

int main(int argc, char **argv) { int n1 = f(3, -5); n1 = g(n1); } int f(int p1, int p2) { int x; int a[3]; ... x = g(a[2]); return x; } int g(int param) { return param * 2; }

OS kernel [protected] stack heap (malloc/free) read/write segment globals read-only segment (main, f, g) main

argc, argv, n1 f p1, p2, x, a

slide-29
SLIDE 29

CMPSC 311 - Introduction to Systems Programming Page

The stack in action

29

int main(int argc, char **argv) { int n1 = f(3, -5); n1 = g(n1); } int f(int p1, int p2) { int x; int a[3]; ... x = g(a[2]); return x; } int g(int param) { return param * 2; }

OS kernel [protected] stack heap (malloc/free) read/write segment globals read-only segment (main, f, g) main

argc, argv, n1 f p1, p2, x, a

slide-30
SLIDE 30

CMPSC 311 - Introduction to Systems Programming Page

The stack in action

30

int main(int argc, char **argv) { int n1 = f(3, -5); n1 = g(n1); } int f(int p1, int p2) { int x; int a[3]; ... x = g(a[2]); return x; } int g(int param) { return param * 2; }

OS kernel [protected] stack heap (malloc/free) read/write segment globals read-only segment (main, f, g) main

argc, argv, n1 f p1, p2, x, a g param

slide-31
SLIDE 31

CMPSC 311 - Introduction to Systems Programming Page

The stack in action

31

int main(int argc, char **argv) { int n1 = f(3, -5); n1 = g(n1); } int f(int p1, int p2) { int x; int a[3]; ... x = g(a[2]); return x; } int g(int param) { return param * 2; }

OS kernel [protected] stack heap (malloc/free) read/write segment globals read-only segment (main, f, g) main

argc, argv, n1 f p1, p2, x, a g param

slide-32
SLIDE 32

CMPSC 311 - Introduction to Systems Programming Page

The stack in action

32

int main(int argc, char **argv) { int n1 = f(3, -5); n1 = g(n1); } int f(int p1, int p2) { int x; int a[3]; ... x = g(a[2]); return x; } int g(int param) { return param * 2; }

OS kernel [protected] stack heap (malloc/free) read/write segment globals read-only segment (main, f, g) main

argc, argv, n1 f p1, p2, x, a g param

slide-33
SLIDE 33

CMPSC 311 - Introduction to Systems Programming Page

The stack in action

33

int main(int argc, char **argv) { int n1 = f(3, -5); n1 = g(n1); } int f(int p1, int p2) { int x; int a[3]; ... x = g(a[2]); return x; } int g(int param) { return param * 2; }

OS kernel [protected] stack heap (malloc/free) read/write segment globals read-only segment (main, f, g) main

argc, argv, n1 f p1, p2, x, a

slide-34
SLIDE 34

CMPSC 311 - Introduction to Systems Programming Page

The stack in action

34

int main(int argc, char **argv) { int n1 = f(3, -5); n1 = g(n1); } int f(int p1, int p2) { int x; int a[3]; ... x = g(a[2]); return x; } int g(int param) { return param * 2; }

OS kernel [protected] stack heap (malloc/free) read/write segment globals read-only segment (main, f, g) main

argc, argv, n1 f p1, p2, x, a

slide-35
SLIDE 35

CMPSC 311 - Introduction to Systems Programming Page

The stack in action

35

int main(int argc, char **argv) { int n1 = f(3, -5); n1 = g(n1); } int f(int p1, int p2) { int x; int a[3]; ... x = g(a[2]); return x; } int g(int param) { return param * 2; }

OS kernel [protected] stack heap (malloc/free) read/write segment globals read-only segment (main, f, g) main

argc, argv, n1

slide-36
SLIDE 36

CMPSC 311 - Introduction to Systems Programming Page

The stack in action

36

int main(int argc, char **argv) { int n1 = f(3, -5); n1 = g(n1); } int f(int p1, int p2) { int x; int a[3]; ... x = g(a[2]); return x; } int g(int param) { return param * 2; }

OS kernel [protected] stack heap (malloc/free) read/write segment globals read-only segment (main, f, g) main

argc, argv, n1 g param

slide-37
SLIDE 37

CMPSC 311 - Introduction to Systems Programming Page

The stack in action

37

int main(int argc, char **argv) { int n1 = f(3, -5); n1 = g(n1); } int f(int p1, int p2) { int x; int a[3]; ... x = g(a[2]); return x; } int g(int param) { return param * 2; }

OS kernel [protected] stack heap (malloc/free) read/write segment globals read-only segment (main, f, g) main

argc, argv, n1 g param

slide-38
SLIDE 38

CMPSC 311 - Introduction to Systems Programming Page

The stack in action

38

int main(int argc, char **argv) { int n1 = f(3, -5); n1 = g(n1); } int f(int p1, int p2) { int x; int a[3]; ... x = g(a[2]); return x; } int g(int param) { return param * 2; }

OS kernel [protected] stack heap (malloc/free) read/write segment globals read-only segment (main, f, g) main

argc, argv, n1

slide-39
SLIDE 39

CMPSC 311 - Introduction to Systems Programming Page

The stack in action

39

int main(int argc, char **argv) { int n1 = f(3, -5); n1 = g(n1); } int f(int p1, int p2) { int x; int a[3]; ... x = g(a[2]); return x; } int g(int param) { return param * 2; }

OS kernel [protected] stack heap (malloc/free) read/write segment globals read-only segment (main, f, g)

slide-40
SLIDE 40

CMPSC 311 - Introduction to Systems Programming Page

Addresses and &

  • &foo produces the virtual address of foo

40

#include <stdio.h> int foo(int x) { return x+1; } int main(int argc, char **argv) { int x, y; int a[2]; printf("x is at %p\n", &x); printf("y is at %p\n", &y); printf("a[0] is at %p\n", &a[0]); printf("a[1] is at %p\n", &a[1]); printf("foo is at %p\n", &foo); printf("main is at %p\n", &main); return 0; }

slide-41
SLIDE 41

CMPSC 311 - Introduction to Systems Programming Page

Pointers

  • type *name; // declare a pointer
  • type *name = address; // declare + initialize a pointer
  • a pointer is a variable that contains a memory address
  • it points to somewhere in the process’ virtual address space

41

int main(int argc, char **argv) { int x = 42; int *p; // p is a pointer to an integer p = &x; // p now stores the address of x printf("x is %d\n", x); printf("&x is %p\n", &x); printf("p is %p\n", p); return 0; }

slide-42
SLIDE 42

CMPSC 311 - Introduction to Systems Programming Page

A stylistic choice

  • C gives you flexibility in how you declare pointers
  • one way can lead to visual trouble when declaring multiple

pointers on a single line

  • the other way is what I prefer

42

int* p1; int *p2; // I prefer int* p1, p2; // bug?; equivalent to int *p1; int p2; int* p1, * p2; // correct

  • r

int *p1, *p2; // correct, preferred

slide-43
SLIDE 43

CMPSC 311 - Introduction to Systems Programming Page

Dereferencing pointers

  • *pointer // dereference a pointer
  • *pointer = value; // dereference / assign
  • dereference: access the memory referred to by a pointer

43

#include <stdio.h> int main(int argc, char **argv) { int x = 42; int *p; // p is a pointer to an integer p = &x; // p now stores the address of x printf("x is %d\n", x); *p = 99; printf("x is %d\n", x); return 0; }

slide-44
SLIDE 44

CMPSC 311 - Introduction to Systems Programming Page

& and *

  • &foo // “address of” foo
  • *pointer // dereference a pointer
  • *pointer = value; // dereference / assign

int x = 42; // x now contains the value 42 int *p; // p is a pointer to an integer p = &x; // p now contains the address of x printf("x is %d\n", x); *p = 99; // store 99 where p points to printf("x is %d\n");

slide-45
SLIDE 45

CMPSC 311 - Introduction to Systems Programming Page

Something curious

  • Let’s try running this program several times:

#include <stdio.h> int main(int argc, char **argv) { int x = 1; int *p = &x; printf("&x: %p; p: %p; &p: %p\n", &x, p, &p); return 0; } [butler]> ./asr &x: 0xbfa521dc; p: 0xbfa521dc; &p: 0xbfa521d8 [butler]> ./asr &x: 0xbf836f5c; p: 0xbf836f5c; &p: 0xbf836f58 [butler]> ./asr &x: 0xbfea39dc; p: 0xbfea39dc; &p: 0xbfea39d8

slide-46
SLIDE 46

CMPSC 311 - Introduction to Systems Programming Page

ASLR

  • Linux uses address-space

randomization for added security

  • linux randomizes:
  • base of stack
  • shared library (mmap) location
  • makes stack-based buffer
  • verflow attacks tougher
  • makes debugging tougher
  • google “disable linux address

space randomization”

46

0x00000000 0xFFFFFFFF

OS kernel [protected] stack shared libraries heap (malloc/free) read/write segment .data, .bss read-only segment .text, .rodata