C Boot Camp: Feb 26, 2017 Ray Axel Jerry
C Boot Camp: Feb 26, 2017 Ray Axel Jerry
C Boot Camp
Ray
Axel
Jerry
Carnegie Mellon
Agenda
■ C Basics
■ Debugging Tools / Demo
■ Appendix
C Standard Library
getopt
stdio.h
stdlib.h
string.h
Carnegie Mellon
C Basics Handout
ssh <andrewid>@shark.ics.cs.cmu.edu
cd ~/private
wget http://cs.cmu.edu/~213/activities/cbootcamp.tar.gz
tar xvpf cbootcamp.tar.gz
cd cbootcamp
make
C Basics
■ The minimum you must know to do well in this class
■ You have seen these concepts before
■ Make sure you remember them.
■ Summary:
■ Pointers/Arrays/Structs/Casting
■ Memory Management
■ Function pointers/Generic Types
■ Strings
■ GrabBag (Macros, typedefs, header guards/files, etc)
Carnegie Mellon
Pointers
■ Stores address of a value in memory
■ e.g. int*, char*, int**, etc
■ Access the value by dereferencing (e.g. *a).
Can be used to read or write a value to given address
■ Dereferencing NULL causes undefined behavior
(usually a segfault)
■ Pointer to type A references a block of sizeof(A) bytes
■ Get the address of a value in memory with the ‘&’
operator
■ Pointers can be aliased, or pointed to same address
Carnegie Mellon
Structs ./structs
■ Collection of values placed under one name in a single
block of memory
■ Can put structs, arrays in other structs
■ Given a struct instance, access the fields using the ‘.’
operator
■ Given a struct pointer, access the fields using the ‘->’
operator
struct inner_s { struct outer_s { outer_s out_inst;
int i; char ar[10]; out_inst.ar[0] = ‘a’;
char c; struct inner_s in; out_inst.in.i = 42;
}; }; outer_s* out_ptr = &out_inst;
out_ptr->in.c = ‘b’;
Carnegie Mellon
Arrays/Strings
■ Arrays: fixed-size collection of elements of the same type
■ Can allocate on the stack or on the heap
■ int A[10]; // A is array of 10 int’s on the stack
■ int* A = calloc(10, sizeof(int)); // A is array of 10
int’s on the heap
Casting
■ Can convert a variable to a different type
■ Integer Casting:
■ Signed <-> Unsigned: Keep Bits - Re-Interpret
■ Small -> Large: Sign-Extend MSB
■ Cautions:
■ Cast Explicitly: int x = (int) y instead of int x = y
■ Casting Down: Truncates data
■ Cast Up: Upcasting and dereferencing a pointer causes undefined
memory access
■
mem_mgmt.c
Memory Management Rules
./mem_valgrind.sh
■ malloc what you free, free what you malloc
■ client should free memory allocated by client code
■ library should free memory allocated by library code
■ Number mallocs = Number frees
■ Number mallocs > Number Frees: definitely a memory leak
■ Number mallocs < Number Frees: definitely a double free
■ Free a malloc’ed block exactly once
■ Should not dereference a freed memory block
■ Only malloc when necessary
■ Persistent, variable sized data structures
■ Concurrent accesses (we’ll get there later in the semester)
Carnegie Mellon
Typedefs ./typedefs
■ Creates an alias type name for a different type
■ Useful to simplify names of complex data types
■ Be careful when typedef-ing away pointers!
struct list_node {
int x;
};
Macros ./macros
■ A way to replace a name with its macro definition
■ No function call overhead, type neutral
■ Think “find and replace” like in a text editor
■ Uses:
■ defining constants (INT_MAX, ARRAY_SIZE)
■ defining simple operations (MAX(a, b))
■ 122-style contracts (REQUIRES, ENSURES)
■ Warnings:
■ Use parentheses around arguments/expressions, to avoid problems after
substitution
■ Do not pass expressions with side effects as arguments to macros
Generic Types
■ void* type is C’s provision for generic types
■ Raw pointer to some memory location (unknown type)
■ Can’t dereference a void* (what is type void?)
■ Must cast void* to another type in order to dereference it
■ Can cast back and forth between void* and other pointer
types
// stack usage:
// stack implementation:
int x = 42; int y = 54;
typedef void* elem;
stack S = stack_new():
push(S, &x);
stack stack_new();
push(S, &y);
void push(stack S, elem e);
int a = *(int*)pop(S);
elem pop(stack S);
int b = *(int*)pop(S);
Carnegie Mellon
Header Files
■ Includes C declarations and macro definitions to be shared
across multiple files
■ Only include function prototypes/macros; implementation code goes in .c file!
■ Usage: #include <header.h>
■ #include <lib> for standard libraries (eg #include <string.h>)
■ #include “file” for your source files (eg #include “header.h”)
■ Never include .c files (bad practice)
// list.h // list.c // stacks.h
struct list_node { #include “list.h” #include “list.h”
int data; struct stack_head {
struct list_node* next; node new_list() { node top;
}; // implementation node bottom;
typedef struct list_node* node; } };
typedef struct stack_head* stack
node new_list(); void add_node(int e, node l) {
void add_node(int e, node l); // implementation stack new_stack();
} void push(int e, stack S);
Carnegie Mellon
Header Guards
■ Double-inclusion problem: include same header file twice
//grandfather.h //father.h //child.h
#include “grandfather.h” #include “father.h”
#include “grandfather.h”
#endif #endif
Debugging
GDB, Valgrind
Carnegie Mellon
GDB
■ No longer stepping through assembly!
Some GDB commands are different:
■ si / si → step / next
■ break file.c:line_num
■ disas → list
■ print <any_var_name> (in current frame)
Valgrind
■ Find memory errors, detect memory leaks
■ Common errors:
■ Illegal read/write errors
■ Use of uninitialized values
■ Illegal frees
■ Overlapping source/destination addresses
■ Typical solutions
■ Did you allocate enough memory?
■ Did you accidentally free stack
variables/something twice?
■ Did you initialize all your variables?
■ Did use something that you just free’d?
■ --leak-check=full
■ Memcheck gives details for each
definitely/possibly lost memory block (where it
was allocated
Carnegie Mellon
Appendix
Carnegie Mellon
C Libraries
Carnegie Mellon
stdio.h
■ Another really useful
library.
■ Used heavily in
cache/shell/proxy labs
■ Used for:
■ argument parsing
■ file handling
■ input/output
■ printf, a fan favorite, comes
from this library!
Carnegie Mellon
Getopt
■ Need to include unistd.h to use int main(int argc, char **argv)
■ Used to parse command-line {
arguments. int opt, x;
■ Typically called in a loop to /* looping over arguments */
retrieve arguments while((opt=getopt(argc,argv,“x:"))>0){
■ Switch statement used to handle switch(opt) {
options case 'x':
■ colon indicates required argument
x = atoi(optarg);
■ optarg is set to value of option
argument break;
■ Returns -1 when no more default:
arguments present printf(“wrong argument\n");
■ See recitation 6 slides for more break;
examples }
}
}
Carnegie Mellon