1 / 61

Pointers and Memory Allocation -L. Grewe

Pointers and Memory Allocation -L. Grewe. Objectives. Why and What are Pointers Create Pointers in C++ Memory Allocation Defined Memory Allocation/Deallocation in C++ Potential Problems with Pointers and Memory. What's the point of pointers?...why?.

hera
Télécharger la présentation

Pointers and Memory Allocation -L. Grewe

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. 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) pC C ... || || || || ... ... pC = pointer to variable C

  6. Pointer Variable • Let’s look at local variables • Q: What’s the value of i? int 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? int i; i = 42; The assignment put number 42 in the cell. The memory address of the 1st 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? int i; i = 42; cout << &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? int i=42; int *i_ptr; • the type of the data that the pointer points to: int • an asterisk (*) • the name of the newly declared pointer: i_ptr

  10. Pointer Variable • Assign the address of i to i_ptr int i=42; int *i_ptr; i_ptr = &i; • 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 int i=42; int *i_ptr; i_ptr = &i; • Two ways to refer to i • cout << i; • cout << *i_ptr; • - dereferencing operator *

  12. Use of & and * in C/C++ &expr Evaluates to the address of the location expr evaluates to *expr Evaluates to the value stored in the address expr evaluates to • 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

  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 b: a: 1ef 13 c(1ef): 13

  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 dereferenceoperator (*) • that can be literally translated to "value pointed by". • Example: a = *b; • a is equal to value pointed by b. b: a: 1ef 13 1ef: 13

  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 ADDR1 ADDR2 ADDR3 ADDR4 ADDR5 ADDR6 * * * Contents11 ADDR11 * * Contents16 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. address value name 42 i 900 p1 ? 900 ? 900 p2 904 904 908 Assignment Operators with Pointers • p2 = p1 900 900 int i = 42; int *p1, *p2; p1 = &i; p2 = p1; Both p1 and p2 point to the same integer

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

  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 <stdio.h> • 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 my_in_file.dat 3 92.66 • 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?

  25. POINTERS my_in_file.dat 3 92.66 • 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? my_out_file.dat • Address_aAddress_b • 92.66 • 3 92.66 • Address_aAddress_b

  26. Arrays and Pointers

  27. Arrays and Pointers 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

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

  29. Traversing an Array 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. • int scores[50]; • int * p = scores; • for( int i = 0; i < 50; i++) • { • cout << *p << endl; • p++; // increment the pointer • }

  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); expr1[expr2] in C is just syntactic sugar for *(expr1 + expr2) s: hello

  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); expr1[expr2] in C is just syntactic sugar for *(expr1 + expr2) s: hello

  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. #include <stdio.h> 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 a=6 b=5 Pointers with Functions (example)

  39. Function Returning an Address 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. • Student * MakeStudent() • { • Student * pS = new Student; • return pS; • } (more)

  40. Receiving a Pointer (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. • Student * pS; • pS = MakeStudent(); • // now pS points to a Student

  41. Pointers and Classes

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

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

  44. STL – Collections • • i.e. vector - Automatic memory management when adding and deleting elements • #include <vector> • void main() { std::vector<int> 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. Pointers to pointers (different than previous slide which was about assigning a pointer to another pointer) • We can also have pointers to pointers: int number= 5; int *ptrtonumber; int **ptrtoptrtonumber; ptrtonumber= &number; *ptrtoptrtonumber= &ptrtonumber; *(*ptrtoptrtonumber)= 6; ptrtonumber number ptrtoptrtonumber 5

  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.

More Related