Presentation is loading. Please wait.

Presentation is loading. Please wait.

Pointers and Memory Allocation -L. Grewe. Objectives Why and What are Pointers Create Pointers in C++ Memory Allocation Defined Memory Allocation/Deallocation.

Similar presentations


Presentation on theme: "Pointers and Memory Allocation -L. Grewe. Objectives Why and What are Pointers Create Pointers in C++ Memory Allocation Defined Memory Allocation/Deallocation."— Presentation transcript:

1 Pointers and Memory Allocation -L. Grewe

2 Objectives Why and What are Pointers Create Pointers in C++ Memory Allocation Defined Memory Allocation/Deallocation in C++ Potential Problems with Pointers and Memory

3 What's the point of pointers?...why? Pointers can be used as variable length arrays. Pointers can be used for advanced data structures. Pointers can be "cheaper" to pass around a program. Can sometimes be difficult to program without them-

4 Motivating Example – for pointers and memory allocation Bag class – bag::CAPACITY constant determines the capacity of every bag – wasteful (if too big) and hard to reuse (if too small) need to change source code and recompile Solution: – provide control over size in running time – dynamic arrays – pointers and dynamic memory

5 Pointers Pointer is a variable that contains the address of a variable –Low level representation of the hardware implementation Typical machine has an array of memory cells (usually bytes (8-bits)) numbered (addressed) consecutively A pointer is a group of cells that can hold an address –On modern computers memory address requires 32 – 64 bits (4 – 8 bytes) ||... CpC pC = pointer to variable C

6 Pointer Variable Let’s look at local variables Q: What’s the value of i? ? 900904 908 912 916 … int i;i By this declaration, a cell of 4 adjacent bytes (in some machines) are allocated in the local memory (called stack memory) Address 9## is just for illustration. Real address may have 64 bits

7 Pointer Variable Let’s assign a value to i Q: How can we get the address? 42 900904 908 912 916 … int i; i = 42;i The assignment put number 42 in the cell. The memory address of the 1 st byte is the address of the variable i – the pointer to i

8 Pointer Variable First let’s have a look at local variables Q: Where can we store &i? 42 900904 908 912 916 … int i; i = 42; cout << &i;i & (ampersand) operator - “address of ” operator - &i is 900 ! -Note: two meanings of &

9 A Pointer Variable A pointer variable can store a memory address in this case to an int Q: How can we point i_ptr to i? 42 ? 900904 908 912 916 … int i=42; int *i_ptr;ii_ptr 1. the type of the data that the pointer points to: int 2. an asterisk (*) 3. the name of the newly declared pointer: i_ptr

10 Pointer Variable Assign the address of i to i_ptr 42 ? 900904 908 912 916 … int i=42; int *i_ptr; i_ptr = &i;ii_ptr What are the results of -cout << i; -cout << i_ptr; -cout << &i_ptr;

11 Pointer Variable The i_ptr holds the address of an integer, not the integer itself 42 900 900904 908 912 916 … int i=42; int *i_ptr; i_ptr = &i;ii_ptr Two ways to refer to i -cout << i; -cout << *i_ptr; - dereferencing operator * - dereferencing operator *

12 Use of & and * in C/C++ When is & used? When is * used? & "address (reference) operator" which gives or produces the memory address of a data variable * “dereferencing operator" which provides the contents in the memory location specified by a pointer &exprEvaluates to the address of the location expr evaluates to *exprEvaluates to the value stored in the address expr evaluates to

13 Address (reference) Operator Operator of address or dereference (&) –It is used as a variable prefix and can be translated as "address of“ –&variable1 can be read as "address of variable1" Example: c = 13; b = &c; // b = 1ef a = *b; // a = 13 1ef b: 13 c(1ef): 13 a:

14 Dereference Operator Using a pointer we can directly access the value stored in the variable pointed by it –precede the pointer identifier with the dereference operator (*) –that can be literally translated to "value pointed by". Example: a = *b; –a is equal to value pointed by b. 1ef b: 13 1ef: 13 a:

15 Concept of Address and Pointers Memory can be conceptualized as a linear set of data locations. Variables reference the contents of a locations Pointers have a value of the address of a given location Contents1 Contents11 Contents16 ADDR1 ADDR2 ADDR3 ADDR4 ADDR5 ADDR6 * * * ADDR11 * * ADDR16

16 Terminology – How to make a pointer in C/C++ Declaring a variable int num = 5; Declaring a pointer int *nptr = 0; Assigning an address to a pointer nptr = &num; Dereferencing a pointer printf("%d",*nptr);

17 Declaring Multiple Pointers How to declare two pointers in a line char *c1_ptr, *c2_ptr; –instead of char* c1_ptr, c2_ptr; TIP: naming convention: for clarity, use _ptr or cursor for pointer variables

18 Assignment Operators with Pointers p2 = p1 int i = 42; int *p1, *p2; p1 = &i; p2 = p1; 42i 900 address value name ?904?908 Both p1 and p2 point to the same integer 900p1904900p2 42 ? ? 900904 908 912 916 … ip1 p2 900 900

19 Assignment Operators with Pointers *p2 = *p1 int i = 42; int *p1, *p2; p1 = &i; *p2 = *p1; 42i 900 address value name ?904 ?p2908 p2 doesn’t point to anywhere, so assigning value to *p2 will cause a running time error! 900p1904 42 ? ? 900904 908 912 916 … ip1 p2 900 X

20 POINTERS Examples of pointer declarations: FILE *fptr; int *a; float *b; char *c; The asterisk, when used as above in the declaration, tells the compiler that the variable is to be a pointer, and the type of data that the pointer points to, but NOT the name of the variable pointed to.

21 An Example Lets look at some code

22 POINTERS Consider the statements: #include int main ( ) { FILE *fptr1, *fptr2 ;/* Declare two file pointers */ int *aptr ;/* Declare a pointer to an int */ float *bptr ;/* Declare a pointer to a float */ int a ;/* Declare an int variable */ float b ;/* Declare a float variable */

23 POINTERS /* Then consider the statements: */ aptr = &a ; bptr = &b ; fptr2 = fopen ( "my_out_file.dat", "w" ) ; fptr1 = fopen ( "my_in_file.dat", "r" ) ; if ( fptr1 != NULL ) { fscanf ( fptr1, "%d%f", aptr, bptr ) ;

24 POINTERS fprintf ( fptr2, "%d %d\n", aptr, bptr ) ; fprintf ( fptr2, "%d %f\n", *aptr, *bptr ) ; fprintf ( fptr2, "%d %f\n", a, b ) ; fprintf ( fptr2, "%d %d\n", &a, &b ) ; return 0 ; } Assuming that the above is part of a program that runs without error and the input file does open, what would be printed to the file By the first fprintf? By the second fprintf? By the third fprintf? By the fourth fprintf? 3 92.66 my_in_file.dat

25 POINTERS fprintf ( fptr2, "%d %d\n", aptr, bptr ) ; fprintf ( fptr2, "%d %f\n", *aptr, *bptr ) ; fprintf ( fptr2, "%d %f\n", a, b ) ; fprintf ( fptr2, "%d %d\n", &a, &b ) ; return 0 ; } Assuming that the above is part of a program that runs without error and the input file does open, what would be printed to the file By the first fprintf? By the second fprintf? By the third fprintf? By the fourth fprintf? 3 92.66 my_in_file.dat Address_a Address_b 392.66 Address_a Address_b my_out_file.dat

26 Arrays and Pointers

27 The name of an array is the pointer to the address containing the first element in the array. Let’s look at how arrays and pointers interact 27

28 Arrays and Pointers int scores[50]; int * p = scores; *p = 99; cout << scores[0]; // "99" p++; // ok scores++; // error: scores is const An array name is assignment-compatible with a pointer to the array's first element. In the following example, *p refers to scores[0].

29 Traversing an Array int scores[50]; int * p = scores; for( int i = 0; i < 50; i++) { cout << *p << endl; p++; // increment the pointer } C and C++ programmers often use pointers to traverse arrays. At one time, such code ran more efficiently, but recent optimizing compilers make array subscripts just as efficient.

30 Array Example char s[6]; s[0] = ‘h’; s[1] = ‘e’; s[2]= ‘l’; s[3] = ‘l’; s[4] = ‘o’; s[5] = ‘\0’; printf (“s: %s\n”, s); s: hello expr1[expr2] in C is just syntactic sugar for *(expr1 + expr2)

31 Array Example 2 – access via pointers char s[6]; *s = ‘h’; *(s + 1) = ‘e’; 2[s] = ‘l’; 3[s] = ‘l’; *(s + 4) = ‘o’; 5[s] = ‘\0’; printf (“s: %s\n”, s); s: hello expr1[expr2] in C is just syntactic sugar for *(expr1 + expr2)

32 Multidimensional Arrays Declaring int myIntArray2D[20][30]; Or int** myIntArray2D; myIntArray2D = new int*[10]; for (int i=0; i<10; i++) myIntArray2D[i] = new int[10]; Accessing an element int x = myIntArray2D[2][6]; // row 3, col 7

33 Destroying 2D array for (int i=0; i<10; i++) delete [] myIntArray2D[i]; delete [] myIntArray2D; NOTE: More dimensions -> more loops!

34 MultiDemensional Array concept via 1D Array A solution: use single dimension array instead: int* myIntArray2D = new int[100]; int x = myIntArray2D[2*10 + 6]; // row 3, col 7 Possible advantage: Can be faster access because of simplified memory structure

35 Functions and Pointers

36 Pointers and Functions Pointers can be used to pass addresses of variables to functions, thus allowing the called function to alter the values stored there.

37 Pointers and Functions If instead of passing the values of the variables to the called function, we pass their addresses, so that the called function can change the values stored in the calling routine. This is known as "call by reference" since we are referencing the variables. The following shows the swap function modified from a "call by value" to a "call by reference". Note that the values are now actually swapped when the control is returned to main function.

38 Pointers with Functions (example) #include void swap ( int *a, int *b ) ; int main ( ) { int a = 5, b = 6; printf("a=%d b=%d\n",a,b) ; swap (&a, &b) ; printf("a=%d b=%d\n",a,b) ; return 0 ; } void swap( int *a, int *b ) { int temp; temp= *a; *a= *b; *b = temp ; printf ("a=%d b=%d\n", *a, *b); } Results: a=5 b=6 a=6 b=5

39 Function Returning an Address Student * MakeStudent() { Student * pS = new Student; return pS; } A function can return the address of an object that was created on the heap. In this example, the function's return type is pointer to Student. (more)

40 Receiving a Pointer Student * pS; pS = MakeStudent(); // now pS points to a Student (continued)... The caller of the function can receive the address and store it in a pointer variable. As long as the pointer remains active, the Student object is accessible.

41 Pointers and Classes 41

42 Pointers in Classes class Student { public: Student(); ~Student(); private: string * courses; // array of course names int count; // number of courses }; // more... Pointers are effective when encapsulated in classes, because you can control the pointers' lifetimes.

43 Pointers in Classes Student::Student() { courses = new string[50]; count = 0; } Student::~Student() { delete [] courses; } The constructor creates the array, and the destructor deletes it. Very little can go wrong,...

44 STL – Collections i.e. vector - Automatic memory management when adding and deleting elements #include void main() { std::vector intList; intList.push_back(10); intList.push_back(12); std::cout << intList[1] << std::endl; intList.clear(); }

45 More Pointer Manipulation

46 Assigning Pointers to Pointers Must be of the same type If not, must use a cast operator Exception is type void –Generic pointer –Can be assigned to any pointer type –Any pointer type can be assigned to it –Cannot be dereferenced (must cast it first)

47 Assigning Pointers to Pointers int num = 1234567890; /*0x499602D2*/ char ch = 'A'; int *iptr = &num; char *cptr = &ch; iptr = (int *)cptr; /*cast char pointer to integer pointer*/ printf("*iptr=%c\n",*iptr); /* *iptr=A (no data lost)*/ iptr = &num; cptr = (char *)iptr; /*cast integer pointer to char pointer*/ printf("*cptr=%d\n",*cptr); /* *cptr=-46 (loss of data)*/ /*0x499602D2 => D2 => 1101 0010 => -46*/

48 We can also have pointers to pointers: Pointers to pointers (different than previous slide which was about assigning a pointer to another pointer) int number= 5; int *ptrtonumber; int **ptrtoptrtonumber; ptrtonumber= &number; *ptrtoptrtonumber= &ptrtonumber; *(*ptrtoptrtonumber)= 6; 5 ptrtonumber ptrtoptrtonumber number

49 Generic Pointer - void * int num = 1234567890; char ch = 'A'; int *iptr = &num; char *cptr = &ch; void *vptr = NULL; vptr = iptr; printf( “ *vptr=%d\n",*((int *)vptr)); /* *vptr=1234567890*/ /* cast void to int pointer*/ vptr = cptr; printf( “ *vptr=%c\n",*((char *)vptr)); /* *vptr=A*/ /* cast void to a char pointer*/

50 Arithmetic and Logical Operations on Pointers A pointer may be incremented or decremented An integer may be added to or subtracted from a pointer. Pointer variables may be subtracted from one another. Pointer variables can be used in comparisons, but usually only in a comparison to NULL.

51 Arithmetic Operations on Pointers When an integer is added to or subtracted from a pointer, the new pointer value is changed by the integer times the number of bytes in the data variable the pointer is pointing to. For example, if the pointer valptr contains the address of a double precision variable and that address is 234567870, then the statement: valptr = valptr + 2; would change valptr to 234567886

52 Problems with Pointers (part 1) 52

53 Memory leaks If we allocate memory but don't free it this is a "memory leak" void my_function (void) { int *a; a= malloc(100*sizeof(int)); /* Do something with a*/ /* Oops – forgot to free a */ } Every time we call this function it "steals" 100 ints worth of memory. As we call this function more the computers memory will fill up.

54 Rogue pointers Rogue pointers are pointers to unassigned memory. If we try to access rogue pointers we will be writing to unassigned memory int *calc_array (void) { int *a; int b[100]; /* Calculate stuff to go in b */ a= b; /* Make a point to the start of b*/ return a; /* Ooops – this isn't good */ }

55 Dangling Pointers double * pD = new double; *pD = 3.523;. delete pD; // pD is dangling.... *pD = 4.2; // error! A dangling pointer is created when you delete its storage and then try to use the pointer. It no longer points to valid storage and may corrupt the program's data.

56 Avoid Dangling Pointers delete pD; pD = NULL;. if( pD != NULL ) // check it first... *pD = 4.2; To avoid using a dangling pointer, assign NULL to a pointer immediately after it is deleted. And, of course, check for NULL before using the pointer.

57 Another possible problem with Pointers class Student { public: Student(); ~Student(); private: string * courses; // array of course names int count; // number of courses }; // more... When you try to copy a Class that has a pointer for a variable. RECALL ----

58 Lets make an instance of our class &copy it Student X; Student Y(X); // construct a copy X.AddCourse("cop 3337"); cout << Y.GetCourse(0); // "cop 3337"...except when making a copy of a Student object. The default copy constructor used by C++ leads to problems. In the following example, a course assigned to student X AFTER THE COPY ends up in the list of courses for student Y.

59 Pointers in Classes Student::Student(const Student & S2) { count = S2.count; courses = new string[count]; for(int i = 0; i < count; i++) courses[i] = S2.courses[i]; } To prevent this sort of problem, we create a copy constructor that performs a so-called deep copy of the array from one student to another.

60 Pointers in Classes Student & Student::operator =(const Student & S2) { delete [] courses; // delete existing array count = S2.count; for(int i = 0; i < count; i++) courses[i] = S2.courses[i]; return *this; } For the same reason, we have to overload the assignment operator.

61 C++ Containers in Classes class Student { public: Student(); private: vector courses; }; When you use Standard C++ containers such as lists and vectors in classes, there is no problem with the default copy constructor in C++. All containers are experts at allocating and copying themselves.


Download ppt "Pointers and Memory Allocation -L. Grewe. Objectives Why and What are Pointers Create Pointers in C++ Memory Allocation Defined Memory Allocation/Deallocation."

Similar presentations


Ads by Google