Download presentation
Presentation is loading. Please wait.
1
Pointers
2
Why pointers? - low-level, but efficient manipulation of memory - dynamic objects Objects whose memory is allocated during program execution. ( Dynamic objects can survive after the function ends in which they were allocated). Dynamic objects allow flexible-sized arrays and lists
3
Pointers A pointer is a variable used for storing the address of a memory cell. We can use the pointer to reference this memory cell, so to ‘manipulate’ it! 100 ……1024… Memory address:1024 10032 … 1020 Integer a Pointer p n Object whose value represents the location (memory address) of another object int a; int* p;
4
Getting an address: address operator & int a=100; “&a” “the address of a” 100………… Memory address:1024 int a = 100; cout << a; 100 Cout << &a; 1024 … 1020 a
5
Define a pointer type variable: T* Examples of (uninitialized) pointers int* ip; char* s; int *ip; // ip is a pointer to an int char *s; // s is a pointer to a char TypeName *variablename; int *p; Each type of object (variable) has a pointer type, therefore a pointer variable of that type. TypeName* variablename; int* p; equivalent
6
Store the address in a pointer variable The value of pointer p is the address of variable a 10088…1024… Memory address:102410032 … 1020 ap int a = 100; int* p = &a; cout << a << " " << &a <<endl; cout << p << " " << &p <<endl; Result is: 100 1024 1024 10032 p is pointing to a A pointer is also a variable, so it has its own memory address
7
Dereferencing Operator * We can access to the value stored in the variable pointed to by preceding the pointer with the “star” operator (*), 10088…1024… Memory address:102410032 … 1020 int a = 100; int* p = &a; cout << a << endl; cout << &a << endl; cout << p << " " << *p << endl; cout << &p << endl; a p *p gives 100
8
An asterisk (‘*’) has two usages In a definition, an asterisk indicates that the object is a pointer. char* s; // s is of type pointer to char (char *s; is possible) In expressions, an asterisk before a pointer indicates the object the pointer pointed to, called dereferencing int i = 1, j; int* ptr; // ptr is an int pointer ptr = &i; // ptr points to i j = *ptr + 1;// j is assigned 2 cout << *ptr << j << endl; // display " 12 "
9
Summary on two operators * and & * has two usages: - pointer - dereferencing & has two usages: - getting address - reference (‘call by ref’, see later)
10
Null Address 0 is a pointer constant that represents the empty or null address Indicates that pointer is not pointing to storage of a valid object Cannot dereference a pointer whose value is null int* ptr; ptr = 0; cout << *ptr << endl; // invalid, ptr // does not point to // a valid int
11
Example #include using namespace std; int main (){ int value1 = 5, value2 = 15; int* p1; int* 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; } Result: Value1 is 10 Value2 is 20
12
Another Pointer Example int a = 3; char s = ‘z’; double d = 1.03; int* pa = &a; char* ps = &s; double* pd = &d; cout << sizeof(pa) << sizeof(*pa) << sizeof(&pa) << endl; cout << sizeof(ps) << sizeof(*ps) << sizeof(&ps) << endl; cout << sizeof(pd) << sizeof(*pd) << sizeof(&pd) << endl;
13
Writing pointer type properly in C++ … int *a, *b; a, b are both integer pointers int* a, b; a is integer pointer, b is just integer! typedef int* IntPt; IntPt a, b; typedef int MyInt; MyInt k; int k; int* a; int* b; ? Recommended:
14
Traditional Pointer Usage void swap(char* ptr1, char* ptr2){ char temp = *ptr1; *ptr1 = *ptr2; *ptr2 = temp; } int main() { char a = 'y'; char b = 'n'; swap(&a, &b); cout << a << b << endl; return 0; } Use pass-by-value of pointers to ‘change’ variable values C language does not have ‘call by reference’, only ‘call by value’!
15
Reference: T& l int& b a; l b is an alternative name for a void f(int& b) {}; int main() { int a; f(a); }
16
Pass by reference (better than ‘pointers’) void swap(char& y, char& z) { char temp = y; y = z; z = temp; } int main() { char a = 'y'; char b = 'n'; swap(a, b); cout << a << b << endl; return 0; } y, z are ‘references’, only names, not like ptr1, ptr2 that are variables
17
Pointer to ‘Struct’ struct Date {…}; Date d={1,10,2009}; Date* pd = &d; (*pd).day=2; (*pd).month=11; Or pd->day=2; pd->month=11;
18
Pointers and arrays
19
Arrays are pointers! The name of an array points only to the first element not the whole array. 1000 1012 1016 1004 1008
20
#include Using namespace std; void main (){ // Demonstrate array name is a pointer constant 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 */ Array name is a pointer constant
21
Result is: 2 #include Using namespace std; void main(){ int a[5] = {2,4,6,8,22}; cout << *a << " " << a[0] << " " << *(&a[0]);..." } //main 2 4 8 6 22 a[4] a[0] a[2] a[1] a[3] Dereference of an array name This element is called a[0] or *a
22
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 Using namespace std; void main(){ int a[5] = {2,4,6,8,22}; int* p = a; int i = 0; cout << a[i] << " " << *p;... } 2 4 8 6 22 a[4] a[0] a[2] a[1] a[3] a p a Array name as pointer 2 2
23
Multiple Array Pointers Both a and p are pointers to the same array. 2 4 #include Using namespace std; void main(){ int a[5] = {2,4,6,8,22}; int* p = &a[1]; cout << a[0] << " " << p[-1]; cout << a[1] << " " << p[0];... } 2 4 8 6 22 a[4] a[0] a[2] a[1] a[3] p P[0] A[0]
24
Pointer Arithmetic Given a pointer p, p+n refers to the element that is offset from p by n positions. 2 4 8 6 22 a a + 2 a + 4 a + 3 a + 1 p p + 2 p + 3 p - 1 p + 1
25
*(a+n) is identical to a[n] Dereferencing Array Pointers a[3] or *(a + 3) 2 4 8 6 22 a a + 2 a + 4 a + 3 a + 1 a[2] or *(a + 2) a[1] or *(a + 1) a[0] or *(a + 0) a[4] or *(a + 4)
26
Summary * two usages: - pointer type definition: int a; int* p; - dereferencing: *p is an integer variable if p = &a; & two usages: - getting address: p = &a; - reference: int& b a; b is an alternative name for a First application in passing parameters (‘swap’ example) int a=10; int b=100; int* p; int* q; p=&a; q=&b; p = q; *p = *q; ? ?
27
a[n]: like a vector, an array a+n *(a+n): like a ‘sequence’ or a ‘list’ Two ways of manipulating an array ‘a’ points to the first element
28
Dynamic Objects
29
Memory Management Static Memory Allocation Memory is allocated at compiling time Dynamic Memory Memory is allocated at running time { int a[200]; … } { int n; cin >> n; a[n]??? }
30
Static vs. Dynamic Objects Static object Memory is acquired automatically Memory is returned automatically when object goes out of scope Dynamic object Memory is acquired by program with an allocation request new operation Dynamic objects can exist beyond the function in which they were allocated Object memory is returned by a deallocation request delete operation
31
Creating a variable (object): new T Syntax ptr = new SomeType; where ptr is a pointer of type SomeType p Uninitialized int variable Example int* p = new int; ‘new’ does two things: 1. Create a variable of given type 2. Point the pointer p to the variable
32
Destructing a variable (object): delete p 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 ‘delete’ does two things: 1. Return the pointed object to the system 2. Point the pointer p to NULL
33
Dynamic Arrays (a collection of variables) Syntax for allocation: 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 Syntax for de-allocation: delete[] p; Because of the flexible pointer syntax, p can be considered to be an array p = new T[size];delete[] p;
34
Example Dynamic Memory Allocation Request for “ unnamed ” memory from the Operating System int* p, n=10; p = new int; p = new int[100]; p p p = new int[n]; p
35
Freeing (or deleting) Memory
36
Allocation Example Need an array of unknown size main() { int n; 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... } int grades[n];
37
Dangling Pointer Problem int* A = new int[5]; for(int i=0; i<5; i++) A[i] = i; int* B = A; delete[] A; B[0] = 1; // illegal!
38
Memory Leak Problem int* A = new int[5]; for(int i=0; i<5; i++) A[i] = i; A = new int[5]; A 0 1 2 3 4 2
39
Static variables (objects)Dynamic variables (objects) A (direct) named memory locationA static part (pointer) + (indirect) nameless memory location (dynamic part) int a; a = 20; int* pa; pa = new int; *pa = 20; 20 a pa static dynamic Summary
40
int* p = new int; *p = 10; delete p; p 10 p int* p = new int[100]; for (i=1;i<100,i++) p[i] = 10; delete[] p; Simple dynamic variable Dynamic array ‘delete p’ is not sufficient for an array!!! ‘delete’ two actions: 1. Return the object pointed to 2. Point the pointer p to NULL 10
41
Good practice Logically, Initialize a pointer with NULL Always check a pointer before usage if (p != NULL) *p
42
n=100; int* p = new int[n]; N=150; P[130]??? Bad examples { int n; cin >> n; a[n]??? } It’s possible, but not standard, Do: int* a = new int[n]; No! the array stays with the size 100.
43
More pointers
44
Pointers to pointers
45
Pointer to pointer: T** int a; int* p; int** q; a = 58; p = &a; q = &p; a pq 58 a, *p, and **q are the same object whose value is 58! But q = &a is illegal!
46
Pointer to pointers and 2D arrays
47
Pointer of pointers & 2D Arrays table[0] or *( table + 0 ) table[1] or *( table + 1 ) table[2] or *( table + 2 ) int table[3][4]; for(int i=0; i<3; i++){ for(int j=0; j<4; j++) cout << *(*(table+i) +j); cout << endl; } table[i][j]What is **table ? table + 2 table table + 1
48
table and table[0] are of the same address int table[2][2] = {{0,1}, {2,3}}; cout << table << endl; cout << *table << endl; //same as above cout << table[0] << endl; // same as above cout << *table[0] << endl; cout << table[0][0] << endl; // same as above cout << **table << end; // same as above 0xffbff938 0
49
Array of Pointers & Pointer to Array a b c An array of Pointers p int a = 1, b = 2, c = 3; int* p[5]; p[0] = &a; p[1] = &b; p[2] = &c; int list[5] = {9, 8, 7, 6, 5}; int* p; p = list;//points to 1 st entry p = &list[0];//points to 1 st entry p = &list[1];//points to 2 nd entry p = list + 1; //points to 2 nd entry A pointer to an array
50
A Dynamic Table A dynamic table is an array of pointers to save space when not all rows of the array are full. int** table; table = new int*[6]; table[0] = new int[4]; table[1] = new int[7]; table[2] = new int[1]; table[3] = new int[3]; table[4] = new int[2]; table[5] = NULL; table[0] table[1] table[2] table[3] table[4] table[5] table
51
table[0][0] = 32; table[0][1] = 18; … 32182412 42141912161113 1811 131413 22 table[0] table[1] table[2] table[3] table[4] table[5] table *(*(table+i)+j) is table[i][j]
52
int m, n; cin >> m >> n >> endl; int** mat; mat = new int*[m]; for (int i=0;i<m;i++) mat[i] = new int[n]; Create a matrix of any dimensions, m by n: int main() { int m, n; cin >> m >> n >> endl; int** matrix; matrix = imatrix(m,n); … } int** imatrix(int m, int n) { int** mat; mat = new int*[m]; for (int i=0;i<n;i++) mat[i] = new int[n]; return mat; } Put it into a function:Ideas:
53
Each row must be deleted individually Be careful to delete each row before deleting the table pointer. Dynamic matrix deallocation void deleteImatrix(int** mat, int m, int n) { for(int i=0; i<m; i++) delete[] mat[i]; delete[] mat; } for(int i=0; i<6; i++) delete[] mat[i]; delete[] mat;
54
‘argc’ is the actual number of arguments ‘argv’ is an array of char*, each pointing to a character int main() int main(int argc, char* argv[]) E.g. a.out 20 30 int main(int argc, char* argv[]) { if (argc != 3) { troubles!!!} int rows = atoi(argv[1]); int col = atoi(argv[2]); } Examples: main() arguments
55
Constantness: object or pointer?
56
(const) object (*const) pointer ‘const’ only modifies a type const T* p constant T, so constant object, const *p ‘const’ only modifies a type as it might be one of them: const T* p T *const p constant pointer const T *const p = constant pointer to constant object (both pointer AND object are constants!) No ‘const*’ operator.
57
Example: 57 A constant object with ‘const’: const int* p; A constant pointer with ‘*const’: int *const p; A constant object AND pointer is: const int *const p;
58
‘const object’ and ‘constant pointer’ Pointer to const object: the content is const, pointer is free int x=10, y=20; const int* pc = &x; pc = &y // OK *pc = 5; // wrong! Const pointer: the pointer is const, content is free int x=10, y=20; Int *const cp = &x; *cp = 5; // OK cp = &y; // wrong! int const *pc
59
59 void f1(const int** bar){ bar[1][1] = 5; // wrong: change int bar[1] = new int[3]; // ok } void f2(int *const *bar){ bar[1][1] = 5; // ok bar[1] = new int[3]; // wrong: change int* bar = new int*[3]; // ok } void f3(int **const bar) { bar[1][1] = 5; // ok bar[1]= new int[3]; // ok bar = new int*[3]; // wrong: change int** } int main(){ int** iptr; int i, j; iptr = new int*[10]; for( i = 0; i < 10; i++ ) iptr[i] = new int[10]; for( i = 0; i < 10; i++ ) for( j = 0; i < 10; i++ ) iptr[i][j] = i*j; f1(iptr); f2(iptr); f3(iptr); } Bad: const int ** bar Bad: int * const * bar Because of ambiguous ‘const int** b’ and ‘const int **b’, so it is ‘const int’! Writing properly matters!!!
60
More examples … 60 int main(){ int i = 3, j = 10; int* ip = &i; *ip = 4; const int* ipc = ip; *ip = 5; // *ipc is now 5 ip = &j; int *const *ipp1 = &ip; // ok const int* const *ipp2 = &ip; // ok const int** ipp3 = &ipc; // ok ipp3 = &ip; // wrong: changing ipp3 // indirectly/inadvertently changes **ipp const int** ipp4 = &ip; // wrong: same reason as above, because if allowed ipp4 //could be changed later return 0; }
61
Pointer to function
62
Function pointers A running program and functions get a certain space in the main memory To store the executable comiled codes and variables A function name is an address pointing to the execution codes of the function When the function is called, the codes and variables are loaded to the call stack A function pointer is a pointer, which points to the address of the function A function pointer can be passed as a parameter to a function int const *pc
63
#include using namespace std; // put a and b in ascending order void ascending( double& a, double& b ){ if( a > b ){ double tmp = a; a = b; b = tmp; } return; } // put a and b in descending order void descending( double & a, double & b ){ if( a < b ){ double tmp = a; a = b; b = tmp; } return; } // function pointer void order( void (*criteria)(double &, double &), double & a, double & b) { (*criteria)(a, b); // same as criteria(a,b); return; } int main(){ double x = 0.7; double y = 0.5; order( ascending, x, y ); cout << x << " " << y << endl; order( descending, x, y ); cout << x << " " << y << endl; return 1; } 0.5 0.7 0.7 0.5 Output:
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.