310 likes | 422 Views
SPL – Practical Session 2. Topics: Makefile C++ Memory Management Pointers. Preprocessor: accepts source code(*. cpp ); r emoves comments; add the content of the include files. Compiler: translates source to assembly code (AND, OR, JMP, SUB etc.).
E N D
SPL – Practical Session 2 • Topics: • Makefile • C++ Memory Management • Pointers
Preprocessor:accepts source code(*.cpp); removes comments; add the content of the include files. Compiler:translates source to assembly code (AND, OR, JMP, SUB etc.). Assembler:creates object code (machine code, 0-s and 1-s, *.o files). Linker: links the object files to an executable and creates an executable machine code; marks the main() as the starting point of the execution.
Example Program We have a program that contains 3 files: • Run.cpp, HelloWorld.cpp, HelloWorld.h • HelloWorld.h included in both .cpp files • Executable should be the file helloWorld
Flags Needed for the Assignments • -c: compile file. input:file.cpp, output: file.o. File is not executable! • -o: parameter to specify name of output . • -g: produces debugging information for debugger. • -Wall: prints all errors/warnings in detail. • -Weffc++: prints errors/warning that violate the guidelines in “Effective C++” and “More Effective C++” books. • Read more: http://www.programmingforums.org/thread7219.html
helloWorld(executable binary) helloWorld.o run.o Run.cpp HelloWorld.h HelloWorld.cpp HelloWorld.h How would you compile it?! Compile HelloWorld.cpp without creating an executable: g++ -c -o helloWorld.o HelloWorld.cpp Compile Run.cpp without creating an executable: g++ -c –o run.o Run.cpp Linking the object files and creating an executable called helloWorld: g++ -o helloWorldrun.ohelloWorld.o
makefile the make utility
Why makefile? • An advanced way to compile your program with a single line! • After creating the makefile ofcourse… • But that needs to be created only once! • Saves a lot of time.. We’ll see how…
Makefile example code helloWorld: run.ohelloWorld.o g++ –Wall –o helloWorldrun.ohelloWorld.o run.o: HelloWorld.h g++ –c Run.cpp helloWorld.o: HelloWorld.h g++ –c HelloWorld.cpp clean: rm –rf ./*.o helloWorld Compiling program: Command: make helloWorld Process: compiles first run.o compiles HelloWorld.o links run.o and helloWorld.o into helloWorld Removing binaries: Command: make clean Process: clean has no dependencies, so it runs the remove command.
How the Makefile Works • T1: D1 D2 Commands To build T1, the make utility will work as follows: • if either D1 orD2 do not exist, build them (recursively). • Check if both D1 andD2 are up to date. If not, build them recursively. • Check the date of (the modification time). If T1 is at least as new as BOTH D1 andD2, we are done; Otherwise, follow the instructions given to build T1
Example from Practical Session 2 Part B – Makefile Segment • CC = g++ • CFLAGS = -g -Wall -Weffc++ • # All Targets • all: hello • # Executable "hello" depends on the files hello.o and run.o. • hello: bin/hello.o bin/run.o • @echo 'Building target: hello' • @echo 'Invoking: C++ Linker' • $(CC) -o bin/hello bin/hello.o bin/run.o • @echo 'Finished building target: hello' • @echo ' ' • # Depends on the source and header files • bin/hello.o: src/HelloWorld.cpp include/HelloWorld.h • $(CC) $(CFLAGS) -c -Linclude -o bin/hello.osrc/HelloWorld.cpp • # Depends on the source and header files • bin/run.o: src/Run.cpp include/HelloWorld.h • $(CC) $(CFLAGS) -c –Linclude -o bin/run.osrc/Run.cpp • #Clean the build directory • clean: • rm -rf bin/* Reading material: http://dev-faqs.blogspot.com/2011/03/simple-makefile-tutorial.html
When you type "make" in your shell, the script will look for a file "makefile" in the same directory and will execute it. • By default, make will only execute the first target in the makefile; so, make sure the first target will cause a complete build. • Important - the space you see to the left of some lines are tabs, and not space characters. • makefile variables are all upper-case, and are referenced using ${VAR_NAME}.
C++ Memory Handling Memory Model, Pointers
Variables in C++ Memory System There are two "kinds" of memory available to a process: • Stack: • Stores local variables of the function. • Removed once the function ends! • Heap: • Contains dynamically allocated variables. • Stays once the function ends, unless cleared before! Read more: http://www.learncpp.com/cpp-tutorial/79-the-stack-and-the-heap/
Pointers • A pointer is a variable that holds the address of some other variable. • In Java, you can’t directly access the memory of such object! Only by reference. • In C++, you can access them directly! Alter them any way you like, without any limitations! Benefit: More control than Java. Drawback: Memory leaks, Memory corruption. • A 64-bit computer can address 264bytes! • Each memory cell is 1 byte. (byte-accessible machines – most of the machines today) • Each pointer takes a static size of 4 bytes in a 32bit OS, and 8bytes in a 64bit OS. • Pointers themselves are saved on the stack.
Java vs. C++ Java’s References C++ Pointers Have access to actual memory locations. Can point to anything! The null value in C++ is the number 0 (memory address 0). • String s = new String("a string"); • The value of the variable 's' is the location of the object on the heap, but we don’t have access to this value! • You can not have a variable that 'points' to a primitive type • String s = null; • means "I don't have the address of any meaningful data"
Pointers – Bit Level ptr1 • Declaration: int x= 5 • int *ptr1 = &x; • integers are of size 4bytes, which means: x: • Char c = ‘z’; char *ptr2 = &c; (‘z’ equals to 122) • Char takes 1byte of memory: c: Decimal to binary conversion: http://www.wikihow.com/Convert-from-Decimal-to-Binary ASCII table: http://www.asciitable.com/ ptr2
MEMORY ADDRESS SPACE Address 1000 1001 1002 1003 1004 1005 1006 81345 81346 81347 ... ... Pointers int x; int *foo; x= 123; foo = &x; x 1 2 3 1000 foo foo contains the address it points at. *foo is the value that foo points at. &x is the address of variable x. &foo is the address of the pointerfoo.
Comparing Pointers • int j = 5; • int i = 5; • int *ptrj1 = &j; • int *ptrj2 = &j; • int *ptri = &i; • True/False: • if (ptrj1 == ptrj2) ? • if (ptrj1 == ptri) ? • if (&ptrj1 == &ptrj2) ? • if (*ptrj1 == *ptri) ? True False False True
Assigning a value to a dereferenced pointer A pointer must have a value before you can dereference it (follow the pointer). int *x; *x=3; int foo; int *x; x = &foo; *x=3; ERROR! x does not point to anything! this is fine x points to foo
Pointers to pointers x some int int *x; int **y; double *z; some *int y some int z some double
Pointers to pointers • Example: • int i = 5; • int *p_i = &i; • int **pp_i = &p_i; • Then: pp_i is memory location of … p_i *pp_i is memory location of … i **pp_i equals… 5
Pointers and Arrays • Array name is basically a const pointer pointing at the beginning of the array. • You can use the [] operator with pointers! • Example: • int A[5]; • Creates a memory block of 5 integers on the stack (5x4bytes) where A (the pointer) points at the beginning of the array -> A[0]. A
Pointers and Arrays int *x; int a[5]={-1,-2,-3,-4,-5}; x = &a[2]; for (int i=0;i<3;i++) x[i]++; x is “the address of a[2] ” a x[i] is the same as a[i+2] x x[0] x[2] x[1]
Pointer arithmetic • Integer math operations can be used with pointers: +, -, ++, --, +=, -= • If you increment a pointer, it will be increased by the size of whatever it points to. • Incrementing pointers will basically make it point to the “next” element in memory. int *ptr = a; *(ptr+2) *(ptr+4) *ptr a[0] a[1] a[2] a[3] a[4] int a[5];
C++ char* • char* is another way to represent strings in C++. (it actually came first - with C!) • char* is an array of chars. • char* arrays are terminated with ‘\0’ – “null terminated strings”. “denotes end of string”. • char *msg= “RPI”; • Length of string? strlen(msg) == 3; msg null 'R‘ 'P‘ 'I‘ \0
Using the Heap • All primitives are stored in the stack, • char* var = “ “; is also stored in the stack. • All that is made without new command are stored in the stack. • Using the new keyword, we can now allocate memory on the heap. • int *i = new int; • string *str = new string(“hi there, heap is cozy!”); • int *arr = new int[5]; • Deleting these objects can be done by using the delete keyword. • delete i; • delete str; • delete[] arr; Safe Delete: if (0 != p){ delete p; p=0; } DO NOT DELETE A PONTER NOT ALLOCATED BY NEW
Pointer Pitfalls • Assigning values to uninitialized, null, or deleted pointers: int *p; int *p = NULL; int *p = new int; *p = 3; *p = 4; delete p; *p = 5; All of these cases end up with segmentation fault!
Dangling Pointer • A pointer that points at nothing: • Example: int *p, *q; p = new int; q = p; delete q; *p = 3; //illegal assignment! • p and q point to the same location, q is deleted, results with p becoming a dangling pointer!
Memory Leaks • Memory leak is when you remove the reference to the memory block, before deleting the block itself. Example: int *p = new int; p = NULL;//or a new other value p points at memory location of type int. p changed to point at null. Result? Must free memory block before changing reference. Memory leak!
A memory leak can diminish the performance of the computer by reducing the amount of available memory. • Eventually, in the worst case, too much of the available memory may become allocated • and all or part of the system or devices stops working correctly, the application fails, or the system slows down. Use valgrind with –leak-check=yes option if your implementation has memory leaks. Valgrind User Manual, The Valgrind Quick Start Guide, Graphical User Interfaces * This is why the –g flag is used when debugging!
Before You Leave! • DO NOT FORGET TO SUBMIT: • Homework0 • Homework1 • Homework2 The Targilonim help your exercise the things we learnt so far! • READ COURSE ANNOUNCEMETNS! • Presentations: www.cs.bgu.ac.il/~jumanan