Understanding Pointers in C++: Syntax, Usage, and Common Pitfalls
This guide provides a comprehensive overview of pointers in C++. It explains what pointers are, how to use them, and their importance in memory management. Key concepts include the syntax for declaring pointers, dereferencing, pointer assignment, and understanding dangling and wild pointers. The guide also covers the difference between shallow and deep copies, illustrating potential pitfalls when using pointers. By following this guide, you will gain a clearer understanding of pointers, enabling better memory management and program stability in your C++ projects.
Understanding Pointers in C++: Syntax, Usage, and Common Pitfalls
E N D
Presentation Transcript
Overview • What are Pointers? • How to use Pointers? • Use of Pointers
Pointer: • A variable that can only store the address of a memory location (usually the address of other variable). x 500 a 300 300 pointer pointee
Syntax: • type * identifier; i.e. int *p; p 258 G pointer
int a=50; • int * p; • p = &a; p 500 ppoints to a a 300 50 300 pointer pointee
* and & operators • Dereferencing *p value at where pointer p is pointing • Address of &a address of variable a
Example: void main(){ int *p; int a=50; p = &a; cout<<a<<endl; cout<<&a<<endl; cout<<p<<endl; cout<<*p<<endl; cout<<&p<<endl; }
Example: void main(){ => int *p; int a=50; p = &a; cout<<a<<endl; cout<<&a<<endl; cout<<p<<endl; cout<<*p<<endl; cout<<&p<<endl; } p 500 pointer
Example: void main(){ int *p; => int a=50; p = &a; cout<<a<<endl; cout<<&a<<endl; cout<<p<<endl; cout<<*p<<endl; cout<<&p<<endl; } p 500 a 300 50 pointer pointee
Example: void main(){ int *p; int a=50; =>p = &a; cout<<a<<endl; cout<<&a<<endl; cout<<p<<endl; cout<<*p<<endl; cout<<&p<<endl; } p 500 a 300 300 50 pointer pointee
Example: void main(){ int *p; int a=50; p = &a; => cout<<a<<endl; // 50 cout<<&a<<endl; cout<<p<<endl; cout<<*p<<endl; cout<<&p<<endl; } p 500 a 300 300 50 pointer pointee
Example: void main(){ int *p; int a=50; p = &a; cout<<a<<endl; // 50 => cout<<&a<<endl; // 300 cout<<p<<endl; cout<<*p<<endl; cout<<&p<<endl; } p 500 a 300 300 50 pointer pointee
Example: void main(){ int *p; int a=50; p = &a; cout<<a<<endl; // 50 cout<<&a<<endl; // 300 => cout<<p<<endl; // 300 cout<<*p<<endl; cout<<&p<<endl; } p 500 a 300 300 50 pointer pointee
Example: void main(){ int *p; int a=50; p = &a; cout<<a<<endl; // 50 cout<<&a<<endl; // 300 cout<<p<<endl; // 300 => cout<<*p<<endl; // 50 cout<<&p<<endl; } p 500 a 300 300 50 pointer pointee
Example: void main(){ int *p; int a=50; p = &a; cout<<a<<endl; // 50 cout<<&a<<endl; // 300 cout<<p<<endl; // 300 cout<<*p<<endl; // 50 => cout<<&p<<endl; // 500 } p 500 a 300 300 50 pointer pointee
Crash!!! Example 2: void main(){ int *p; int a=50; cout<<*p<<endl; } What would be the output? Runtime error!!! p 500 a 300 50 pointer pointee
Dangling Pointer int *p; Note: Dereferencing a dangling pointer is a serious runtime error. p 500 G Dangling pointer pointer
Problem: We can’t differentiate that whether a pointer is dangling or has a valid address. • What’s the solution?
NULL Pointer int *p; p = NULL; // points to // nothing Tip: Always initialize a pointer with NULL if you don’t have a valid address. This can save a lot of your time on debugging. p 500 pointer
Example: void main(){ int *p = NULL; int a=50; p = &a; cout<<a<<endl; cout<<&a<<endl; cout<<p<<endl; cout<<*p<<endl; cout<<&p<<endl; }
Pointer Assignment • An assignment operation b/w two pointers makes them points to the same pointee.
ppoints to a 300 • int a=50; • int * p; • p = &a; • int p2 = p; p 500 p2 200 a 300 300 50 Sharing pointer pointer pointee Note: Pointer assignment only copies the address and not the memory they are pointing to.
Shallow Copy ppoints to a p 500 p2 200 a 300 300 300 50 pointer pointer pointee Sharing
Problem with Shallow Copy What if p delete a? ppoints to a p 500 p2 200 a 300 300 300 50 pointer pointer pointee Wild Pointer
Deep Copy ppoints to a p 500 p2 200 a 300 a2 100 300 100 50 50 pointer pointer pointee pointee
Pointer type and Arithmetic • What is type of pointer? int * p; A pointer has not type!!! It’s the type of variable the pointer p will point to.
Why we need to specify the type of variable a pointer points to?
1. int a=10; int *p = &a; *p = 4; // how many bytes of copy? It would be 1 byte in case a was a char.
2. Pointer & Arrays 40 42 44 46 48 50 52 int arr[ ]={5,6,7,8,4,3,5}; // size of arr? int *p = arr; // why & isn’t use before arr? cout<<arr<<endl; // 40 cout<<p<<endl; // 40 p=p+3; p 500 40 pointer
2. Pointer & Arrays 40 42 44 46 48 50 52 int arr[ ]={5,6,7,8,4,3,5}; // size of arr? int *p = arr; // why & isn’t use before arr? cout<<arr<<endl; // 40 cout<<p<<endl; // 40 p=p+3; cout<<p<<endl; // 46 cout<<*p<<endl; // 8 p 500 40 pointer
Example 3: void main( ){ => int arr[ ]={5,6,7,8,4,3,5}; int *p = arr; cout<< arr<<endl; cout<<*arr<<endl; cout<<*(arr+4)<<endl; cout<<p<<endl; cout<<&p<<endl; cout<<*p<<endl; cout<<p[3]<<endl; cout<<p++<<endl; cout<<++*p<<endl; } 40 42 44 46 48 50 52
Example 3: void main( ){ int arr[ ]={5,6,7,8,4,3,5}; => int *p = arr; cout<< arr<<endl; cout<<*arr<<endl; cout<<*(arr+4)<<endl; cout<<p<<endl; cout<<&p<<endl; cout<<*p<<endl; cout<<p[3]<<endl; cout<<p++<<endl; cout<<++*p<<endl; } 40 42 44 46 48 50 52 p 500 40 pointer
Example 3: void main( ){ int arr[ ]={5,6,7,8,4,3,5}; int *p = arr; => cout<< arr<<endl; // 0x40 cout<<*arr<<endl; cout<<*(arr+4)<<endl; cout<<p<<endl; cout<<&p<<endl; cout<<*p<<endl; cout<<p[3]<<endl; cout<<p++<<endl; cout<<++*p<<endl; } 40 42 44 46 48 50 52 p 500 40 pointer
Example 3: void main( ){ int arr[ ]={5,6,7,8,4,3,5}; int *p = arr; cout<< arr<<endl; // 0x40 => cout<<*arr<<endl; // 5 cout<<*(arr+4)<<endl; cout<<p<<endl; cout<<&p<<endl; cout<<*p<<endl; cout<<p[3]<<endl; cout<<p++<<endl; cout<<++*p<<endl; } 40 42 44 46 48 50 52 p 500 40 pointer
Example 3: void main( ){ int arr[ ]={5,6,7,8,4,3,5}; int *p = arr; cout<< arr<<endl; // 0x40 cout<<*arr<<endl; // 5 => cout<<*(arr+4)<<endl; // 4 cout<<p<<endl; cout<<&p<<endl; cout<<*p<<endl; cout<<p[3]<<endl; cout<<p++<<endl; cout<<++*p<<endl; } 40 42 44 46 48 50 52 p 500 40 pointer
Example 3: void main( ){ int arr[ ]={5,6,7,8,4,3,5}; int *p = arr; cout<< arr<<endl; // 0x40 cout<<*arr<<endl; // 5 cout<<*(arr+4)<<endl; // 4 => cout<<p<<endl; //0x40 cout<<&p<<endl; cout<<*p<<endl; cout<<p[3]<<endl; cout<<p++<<endl; cout<<++*p<<endl; } 40 42 44 46 48 50 52 p 500 40 pointer
Example 3: void main( ){ int arr[ ]={5,6,7,8,4,3,5}; int *p = arr; cout<< arr<<endl; // 0x40 cout<<*arr<<endl; // 5 cout<<*(arr+4)<<endl; // 4 cout<<p<<endl; //0x40 => cout<<&p<<endl; //0x500 cout<<*p<<endl; cout<<p[3]<<endl; cout<<p++<<endl; cout<<++*p<<endl; } 40 42 44 46 48 50 52 p 500 40 pointer
Example 3: void main( ){ int arr[ ]={5,6,7,8,4,3,5}; int *p = arr; cout<< arr<<endl; // 0x40 cout<<*arr<<endl; // 5 cout<<*(arr+4)<<endl; // 4 cout<<p<<endl; //0x40 cout<<&p<<endl; //0x500 => cout<<*p<<endl; // 5 cout<<p[3]<<endl; cout<<p++<<endl; cout<<++*p<<endl; } 40 42 44 46 48 50 52 p 500 40 pointer
Example 3: void main( ){ int arr[ ]={5,6,7,8,4,3,5}; int *p = arr; cout<< arr<<endl; // 0x40 cout<<*arr<<endl; // 5 cout<<*(arr+4)<<endl; // 4 cout<<p<<endl; //0x40 cout<<&p<<endl; //0x500 cout<<*p<<endl; // 5 => cout<<p[3]<<endl; // 8 cout<<p++<<endl; cout<<++*p<<endl; } 40 42 44 46 48 50 52 p 500 40 pointer
Example 3: void main( ){ int arr[ ]={5,6,7,8,4,3,5}; int *p = arr; cout<< arr<<endl; // 0x40 cout<<*arr<<endl; // 5 cout<<*(arr+4)<<endl; // 4 cout<<p<<endl; //0x40 cout<<&p<<endl; //0x500 cout<<*p<<endl; // 5 cout<<p[3]<<endl; // 8 => cout<<p++<<endl; // 0x40 cout<<++*p<<endl; } 40 42 44 46 48 50 52 p 500 40 pointer
Example 3: void main( ){ int arr[ ]={5,6,7,8,4,3,5}; int *p = arr; cout<< arr<<endl; // 0x40 cout<<*arr<<endl; // 5 cout<<*(arr+4)<<endl; // 4 cout<<p<<endl; //0x40 cout<<&p<<endl; //0x500 cout<<*p<<endl; // 5 cout<<p[3]<<endl; // 8 cout<<p++<<endl; // 0x40 => cout<<++*p<<endl; // 7 } 40 42 44 46 48 50 52 p 500 40 pointer
Arrays of Pointer data_type *arr[size]; i.e. int *a[7]; char *c[7]; 40 42 44 46 48 50 52 80 82 84 86 88 90 92
Uses: • Sharing & Cost saving • Pass-by-ref • Dynamic Memory Allocation • Making Complex Data Structures • Linked list, Tree etc.
1. Sharing & cost saving void main(){ int a=5,b=8; swap(&a,&b); } void swap(int *a,int *b){ int t = *a; *a = *b; *b = t; }
2. DMA void main(){ int size=0; int *p=NULL; cout<<“Enter No. of Students”<<endl; cin>>size; p = (int *)malloc(size*sizeof(int)); for(int i=0;i<size;i++){ cout<<“Enter St “<<i<<“ Marks”<<endl; cin>>p[i]; //= cin>>*p; p++; } }
3. Data Structures Data Pointer Data Pointer Data Pointer Data Pointer
References: • Pointer And Memory (http://cslibrary.stanford.edu/102/) • Pointer Basics (http://cslibrary.stanford.edu/106/) • http://www.cprogramming.com/tutorial/c/lesson6.html • http://www.cs.cf.ac.uk/Dave/C/node10.html