Pointers in C: Overview and Usage
Pointers in C are powerful tools that allow for efficient memory manipulation and data handling. By understanding pointers, you can work with dynamically allocated memory, complex data structures, and more. Learn about the benefits and usage of pointers in C programming.
Download Presentation

Please find below an Image/Link to download the presentation.
The content on the website is provided AS IS for your information and personal use only. It may not be sold, licensed, or shared on other websites without obtaining consent from the author.If you encounter any issues during the download, it is possible that the publisher has removed the file from their server.
You are allowed to download the files provided on this website for personal or commercial use, subject to the condition that they are used lawfully. All files are the property of their respective owners.
The content on the website is provided AS IS for your information and personal use only. It may not be sold, licensed, or shared on other websites without obtaining consent from the author.
E N D
Presentation Transcript
Pointers Pass-By-Reference Dynamic Memory Allocation Command-Line Arguments
Overview Working directly with memory locations is beneficial. In C, pointers allow you to: change values passed as arguments to functions (simulate call-by-reference) work directly with memory that has been dynamically allocated efficiently work with complex data types such as large structures, linked lists, and arrays.
Introduction to pointers Definition: A pointer is a variable whose content is the address of a value in memory. On our current Intel x86 machines, the amount of space required to hold a pointer variable is 8 bytes and is not related to the size of the entity to which it points.
Introduction to Pointers To declare a pointer in a program, just use the type it points to followed by *. <type> *variable_name; Examples: int short unsigned char *c; double *d = NULL; *a; *b;
Introduction to Pointers We designate a pointer with an arrow ( ) char a; a char *p; int n; 10 int *q; float x; 7.5 float *r; double *t; double y; 15.2
Introduction to Pointers You can declare a pointer and have it point to (make its value be) that location in memory for the variable called x as follows: int x = 7; // variable x of type integer int *ptr; // a pointer to an integer variable ptr = &x; // pointer points to memory location x The asterisk (*) in the declaration denotes that ptr is to be a pointer and the int indicates the type of data to which ptr will point. The address operator (&) in the third line refers to the address of x.
Introduction to Pointers What is physically going in RAM? int x = 7; int *ptr = &x; address address 20000 90000 7 20000 x ptr 7 * ptr x
Dereferencing a pointer If you want to change the value that ptr is pointing to, you can write the following: *ptr = 25; same effect as, x = 25; In either case, the value at that memory location (x) was changed to 25.
Pointers int a; int b; int c; int *p; int *q; int *r; a b c p q r a = 5; b = 3; p = &b; a 5 b 3 c p q r a 5 b 3 c q = p; r = &c; p q r
Pointers p = &a; *q = 15; a 5 b 15 c p q r a 5 b 15 c 5 *r = *p; p q r a 5 b 15 c 20 *r = a + *q p q r
Dereferencing a pointer The direct value is the address of another memory location. A direct assignment to a pointer variable will change the address of the pointer, not the value at the address that it is pointing to. The indirect value is the value at that other memory location. A pointer directly refers to an address , and the * operator on the pointer will allow you to change the value at that memory location via dereferencing (indirection).
Initialization of pointers Like all variables, pointers must be initialized before they are used. ? int *ptr; ??? pointer to unknown location in this case, ptr may contain a value that is interpreted as a memory address. if the memory address does not exist, you will get a run-time error (segmentation fault). if the memory address is valid, you will either get a run-time error OR
Initialization of pointers /* Example of a common error: failure to initialize a pointer before using it. This program is is FATALLY flawed.... */ int main() { int* ptr; *ptr = 99; // ptr has not been initialized printf("val of *ptr = %d and ptr is %p \n", *ptr, ptr); return 0; }
Initialization of pointers The program may appear to work at times, if the address stored in ptr just happens to be a legal address in the address space of this program. Unfortunately, it may be the address of some other variable whose value is now 99!!! This situation is commonly referred to as a loose pointer and bugs such as these may be very hard to find.
Minimizing latent loose pointer problems Never declare a pointer without initializing it in the declaration. int x; int *xptr = &x; int *ptr = NULL;
Correct use of the pointer int main(void) { int y = 12; int * ptr = &y; printf("y is %d\n", y); *ptr = 99; printf("now y is %d\n\n", y); printf("address of y is: %p\n", &y); printf("contents of ptr is: %p\n", ptr); printf("address of ptr is: %p\n", &ptr); return 0; }
Correct use of the pointer gcc -Wall -o ptrEx pointerEx1.c ./ptrEx y is 12 now y is 99 address of y is: 0x7ffc8f8db98c contents of ptr is: 0x7ffc8f8db98c address of ptr is: 0x7ffc8f8db990
Correct use of the pointer In C, regular local variables that are declared within any basic block are allocated on the runtime stack. /* pointer example with static variable */ #include <stdio.h> int main(void) { int y = 12; int * ptr; static int a; // not stored on the stack ptr = &y; printf("y is %d\n", y); *ptr = 99; printf("now y is %d\n\n", y); printf("address of a is: %p\n", &a); printf("address of y is: %p\n", &y); printf("contents of ptr is: %p\n", ptr); printf("address of ptr is: %p\n", &ptr); return 0; }
Correct use of the pointer gcc -Wall -o ptrEx pointerEx1.c ./ptrEx y is 12 now y is 99 address of a is: 0x601044 address of y is: 0x7ffc8f8db98c contents of ptr is: 0x7ffc8f8db98c address of ptr is: 0x7ffc8f8db990 Note that a is a heap resident variable and has an address far removed from the stack resident y and ptr.
void pointer a void * is a generic type that is not associated with any type. i.e., it is not the address of a character, an integer, a float, a double, or any other type. void *vptr; // pointer to void type int *iptr = NULL; // Null pointer of type int you cannot dereference a void pointer. int a = 55; void *vpter = &a; *vptr = 100; // invalid // cannot dereference vptr
Pointer compatibility pointers have a type associated with them not just pointer types, but pointers to a specific type the size of all pointers is the same (each holds the address on a memory location) the size of the variable that the pointer points to can be different except for a pointer to void, it is invalid to assign a pointer of one type to a pointer of another type a void * can be assigned to a pointer to any type and a pointer to any type can be assigned to a void *
Pointer compatibility Examples: int i = 55; int j = 132; float y = 83.7; void *vptr; int *p; int *q = &j; float *fptr; Valid assignments: vptr = q; p = vptr; // a void pointer being assigned to a pointer of some type vptr = fptr; // assigning a pointer of some type to a void pointer fptr = &y;
Pointer compatibility Examples: int i = 55; int j = 132; float y = 83.7; void *vptr; int *p; int *q = &j; float *fptr; vptr = &i; Invalid assignments: p = fptr; // invalid to assign a float pointer to an int pointer fptr = &i; // invalid to assign a float pointer to point to an int *vptr = 112; // cannot dereference a void pointer
Pointer compatibility Can solve the incompatibility problem by type casting, i.e. you can tell the compiler the type of the data that ptr is pointing to,. int x; char c; char *pc; void *vptr; vptr = (int *)&x; pc = (char *)&x;
Pointers & Arrays Given Notice that aPtr is assigned to a and not &a why?? If an array name is used without a subscript, the meaning is the address of the first element of the array What happens after the third line of code above??
Pointers & Arrays Given the following array declaration: Assume we also declare an integer pointer to point to the array: (What is another way to write this?) Then we can imagine it looking like this: What does the following mean: Which is the same as writing what?? What happens with the following: *(aPtr + 3) aPtr = aPtr + 1;
Pointers & Arrays The name of an array and the address of the first element in the array represent the same thing The name of an array is a pointer constant to the first element of the array So, we could also use :
Pointer Arithmetic & Arrays Pointer Arithmetic & Arrays If scorePtr is pointing to a specific element in the array and n is an integer, scorePtr + n is the pointer value n elements away We can access elements of the array either using the array notation or pointer notation If scorePtr points to the first element, the following two If scorePtr is pointing to a specific element in the array and n is an integer, scorePtr + n is the pointer value n elements away We can access elements of the array either using the array notation or pointer notation If scorePtr points to the first element, the following two expressions are equivalent: expressions are equivalent: Array notation Array notation scores[n] scores[n] *(scorePtr + n) Pointer notation *(scorePtr + n) Pointer notation
First, Pass-By-Value. Whats wrong with this? void swap(int first, int second) { // declare a temp integer and swap the // two parameters int temp; temp = first; first = *second; second = temp; printf("first is %d and second is %d\n", *first, *second); } Function call: swap(a, b);
Pass-By-Reference void swap(int *first, int *second) { // declare a temp integer and swap the // two parameters int temp; temp = *first; *first = *second; *second = temp; printf("first is %d and second is %d\n", *first, *second); } Function call: swap(&a, &b);
Pointers and Dynamic Allocation of Memory So far, we have always allocated memory for regular variables that are located on the stack Size of such variables must be known at compile time Sometimes convenient to allocate memory at run time System maintains a second storage area called the heap Functions calloc and malloc allocate memory as needed of size needed
Pointers and Dynamic Allocation of Memory: calloc calloc Used to dynamically create an array in the heap Contiguous allocation Initialized to binary zeros Must Takes two arguments 1. Number of array elements 2. Amount of memory required for one element Use sizeof operator Returns Void pointer if successful NULL if unsuccessful
Pointers and Dynamic Allocation of Memory: calloc
Pointers and Dynamic Allocation of Memory: malloc malloc Used to dynamically get memory from heap Contiguous allocation No initialization Must Takes one argument Total amount of memory required Returns Void pointer if successful NULL if unsuccessful
Pointers and Dynamic Allocation of Memory: malloc
Pointers and Dynamic Allocation of Memory: free free Used to dynamically release memory back to heap Contiguous deallocation Must Takes one argument Pointer to beginning of allocated memory Good idea to also NULL pointer if reusing
Pointers and Dynamic Allocation of Memory: free
Command-Line Arguments Arguments passed to a program upon execution are called command-line arguments. The main() function signature changes from int main(void) to int main(int argc, char *argv[]) The first argument argc holds the number of items types at the command prompt, including the executable name. The second argument char *argv[] is an array of character pointers, each pointer pointing to the arguments typed in at the command-line.
Command-Line Arguments With the reverse_echo program, if you type ./a.out testing 1 2 3 at the command-prompt, argc would have the value 5, and argv[] would look like this:
sscanf() We have used scanf() to scan input from the keyboard. sscanf() scans an array (or string) already in memory and reads each item into a pointer that points to the address (just like scanf()) int sscanf( buffer, format(s), arg(s) ) where buffer is the given array, or string (the source) format is the format specifier (%d, %f, %s, etc) arg is the pointer(s) to the address of each argument (destinations)
sscanf() Example 1: int numberOfArgs = 0; numberOfArgs = sscanf(myIntArray, %d, %d, %d , &num1, &num2, &num3); Example 2: if sample run is ./a.out John 7 12 printf( Hello %s.\n , argv[1]); sscanf(argv[2], %d , &birthMonth); sscanf(argv[3], %d , &birthDay);