1 / 31

Efficient C++ Memory Management Techniques and Makefile Creation

Explore C++ memory management, pointers, and the practical creation of a Makefile for efficient program compilation. Understand memory types, pointer usage, and the benefits of Make.

Download Presentation

Efficient C++ Memory Management Techniques and Makefile Creation

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. SPL – Practical Session 2 • Topics: • Makefile • C++ Memory Management • Pointers

  2. 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.

  3. 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

  4. 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

  5. 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

  6. makefile the make utility

  7. 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…

  8. 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.

  9. 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

  10. 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

  11. 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}.

  12. C++ Memory Handling Memory Model, Pointers

  13. 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/

  14. 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.

  15. 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"

  16. 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

  17. 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.

  18. 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

  19. 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

  20. Pointers to pointers x some int int *x; int **y; double *z; some *int y some int z some double

  21. 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

  22. 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

  23. 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]

  24. 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];

  25. 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

  26. 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

  27. 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!

  28. 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!

  29. 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!

  30.  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!

  31. 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

More Related