Pointers and dynamic objects
Topics • Pointers – Memory addresses – Declaration – Dereferencing a pointer – Pointers to pointer • Static vs. dynamic objects – new and delete
Computer Memory • Each variable is assigned a memory slot (the size depends on the data type) and the variable’s data is stored there Memory address: 1020 1024 1032 … … … … 100 1024 a Variable a’s value, i.e., 100, is int a = 100; stored at memory location 1024
Pointers • A pointer is a variable used to store the address of a memory cell. • We can use the pointer to reference this memory cell Memory address: 1020 1024 1032 … … … … 100 1024 integer pointer
Pointer Types • Pointer – C++ has pointer types for each type of object • Pointers to int objects • Pointers to char objects • Pointers to user-defined objects (e.g., RationalNumber ) – Even pointers to pointers • Pointers to pointers to int objects
Pointer Variable • Declaration of Pointer variables type * pointer_name; //or type *pointer_name; where type is the type of data pointed to (e.g. int, char, double) Examples: int *n; RationalNumber *r; int **p; // pointer to pointer
Address Operator & • The " address of " operator ( & ) gives the memory address of the variable – Usage: &variable_name Memory address: 1020 1024 … … … … … 100 a int a = 100; //get the value, cout << a; //prints 100 //get the memory address cout << &a; //prints 1024
Address Operator & Memory address: 1020 1024 1032 … … … … 88 100 a b #include <iostream> using namespace std; Result is: void main(){ The address of a is: 1020 int a, b; The address of b is: 1024 a = 88; b = 100; cout << "The address of a is: " << &a << endl; cout << "The address of b is: " << &b << endl; }
Pointer Variables Memory address: 1020 1024 1032 … … … 88 100 1024 a p int a = 100; Result is: int *p = &a; 100 1024 cout << a << " " << &a <<endl; 1024 1032 cout << p << " " << &p <<endl; • The value of pointer p is the address of variable a • A pointer is also a variable, so it has its own memory address
Pointer to Pointer What is the output? 58 58 58
Dereferencing Operator * • We can access to the value stored in the variable pointed to by using the dereferencing operator ( * ), Memory address: 1020 1024 1032 … … … 88 100 1024 a p int a = 100; Result is: int *p = &a; 100 cout << a << endl; 1024 cout << &a << endl; 1024 100 cout << p << " " << *p << endl; 1032 cout << &p << endl;
Don’t get confused • Declaring a pointer means only that it is a pointer: int *p; • Don’t be confused with the dereferencing operator, which is also written with an asterisk ( * ). They are simply two different tasks represented with the same sign int a = 100, b = 88, c = 8; int *p1 = &a, *p2, *p3 = &c; p2 = &b; // p2 points to b p2 = p1; // p2 points to a b = *p3; //assign c to b *p2 = *p3; //assign c to a Result is: cout << a << b << c; 888
A Pointer Example Memory Layout The code Box diagram main void doubleIt(int x, int * p) p 8192 { 16 a (8200) *p = 2 * x; doubleIt } x 9 int main(int argc, const (8196) char * argv[]) { a 16 main int a = 16; doubleIt (8192) doubleIt(9, &a); return 0; 9 x } a gets 18 p
Another Pointer Example #include <iostream> Result is using namespace std; int main (){ value1==10 / value2==20 int value1 = 5, value2 = 15; int *p1, *p2; p1 = &value1; // p1 = address of value1 p2 = &value2; // p2 = address of value2 *p1 = 10; // value pointed to by p1=10 *p2 = *p1; // value pointed to by p2= value // pointed to by p1 p1 = p2; // p1 = p2 (pointer value copied) *p1 = 20; // value pointed to by p1 = 20 cout << "value1==" << value1 << "/ value2==" << value2; return 0; }
Traditional Pointer Usage void IndirectSwap(char *Ptr1, char *Ptr2){ char temp = *Ptr1; *Ptr1 = *Ptr2; *Ptr2 = temp; } int main() { char a = 'y'; char b = 'n'; IndirectSwap(&a, &b); cout << a << b << endl; return 0; }
Pass by Reference void IndirectSwap(char& y, char& z) { char temp = y; y = z; z = temp; } int main() { char a = 'y'; char b = 'n'; IndirectSwap(a, b); cout << a << b << endl; return 0; }
Pointers and Arrays The name of an array points only to the first element not the whole array. 1000 1004 1008 1012 1016
Array Name is a pointer constant #include <iostream> using namespace std; void main (){ int a[5]; cout << "Address of a[0]: " << &a[0] << endl << "Name as pointer: " << a << endl; } Result : Address of a[0]: 0x0065FDE4 Name as pointer: 0x0065FDE4
Dereferencing An Array Name This element is called a[0] a[0] or *a *a #include <iostream> using namespace std; a[0] 2 void main(){ a a[1] 4 int a[5] = {2,4,6,8,22}; cout << *a << " " a[2] 6 << a[0]; a[3] 8 } //main a[4] 22 a
Array Names as Pointers To access an array, any pointer to the first element can be used instead of the name of the array. We could replace *p by *a #include <iostream> using namespace std; p a void main(){ 2 2 2 a[0] int a[5] = {2,4,6,8,22}; 4 a[1] int *p = a; cout << a[0] << " " 6 a[2] << *p; 8 a[3] } a[4] 22 a
Pointer Arithmetic Given a pointer p, p+n refers to the element that is offset from p by n positions. p - 1 2 a p 4 a + 1 p + 1 6 a + 2 p + 2 8 a + 3 p + 3 a + 4 22
Dereferencing Array Pointers 2 a[0] or *(a + 0) a 4 a + 1 a[1] or *(a + 1) 6 a + 2 a[2] or *(a + 2) 8 a + 3 a[3] or *(a + 3) 22 a[4] or *(a + 4) a + 4 *(a+n) is identical to a[n] Note: flexible pointer syntax
Array of Pointers & Pointers to Array a p b c A pointer to an array An array of Pointers int a = 1, b = 2, c = 3; int list[5] = {9, 8, 7, 6, 5}; int *p[5]; int *p; P = list;//points to 1 st entry p[0] = &a; P = &list[0];//points to 1 st entry p[1] = &b; P = &list[1];//points to 2 nd entry p[2] = &c; P = list + 1; //points to 2 nd entry
Storing 2D Array in 1D Array int twod[3][4] = {{0,1,2,3}, {4,5,6,7}, {8,9,10,11}}; int oned[12]; for(int i=0; i<3; i++){ for(int j=0; j<4 ; j++) oned[i*4+j] = twod[i][j]; }
Dynamic Objects
Memory Management • Static Memory Allocation – Memory is allocated at compilation time • Dynamic Memory – Memory is allocated at running time
Static vs. Dynamic Objects • Dynamic object • Static object (variables as declared in function calls) – Memory is acquired by – Memory is acquired program with an allocation automatically request • new operation – Memory is returned – Dynamic objects can exist automatically when object beyond the function in which goes out of scope they were allocated – Object memory is returned by a deallocation request • delete operation
Memory Allocation new delete { int* ptr; int a[200]; ptr = new int[200]; … … } delete [] ptr;
Object (variable) creation: New Syntax ptr = new SomeType; where ptr is a pointer of type SomeType Example int* p = new int; Uninitialized int variable p
Object (variable) destruction: Delete Syntax delete p; storage pointed to by p is returned to free store and p is now undefined Example int* p = new int; *p = 10; delete p; p 10
Array of New: dynamic arrays • Syntax P = new SomeType[Expression]; – Where • P is a pointer of type SomeType • Expression is the number of objects to be constructed -- we are making an array • Because of the flexible pointer syntax, P can be considered to be an array
Example Dynamic Memory Allocation Request for “ unnamed ” memory from the Operating System new p int *p, n=10; p = new int; new p = new int[100]; p new p p = new int[n];
Memory Allocation Example Want an array of unknown size main() { cout << “How many students? “; cin >> n; int *grades = new int[n]; for(int i=0; i < n; i++){ int mark; cout << “Input Grade for Student” << (i+1) << “ ? :”; cin >> mark; grades[i] = mark; } . . . printMean( grades, n ); // call a function with dynamic array . . . }
Freeing (or deleting) Memory
A Simple Dynamic List Example cout << "Enter list size: "; int n; cin >> n; int *A = new int[n]; if(n<=0){ cout << "bad size" << endl; return 0; } initialize(A, n, 0); // initialize the array A with value 0 print(A, n); A = addElement(A,n,5); //add an element of value 5 at the end of A print(A, n); A = deleteFirst(A,n); // delete the first element from A print(A, n); selectionSort(A, n); // sort the array (not shown) print(A, n); delete [] A;
Initialize void initialize(int list[], int size, int value){ for(int i=0; i<size; i++) list[i] = value; }
Recommend
More recommend