# Pointers in C Rohit Khokher

## Presentation on theme: "Pointers in C Rohit Khokher"— Presentation transcript:

Pointers in C Rohit Khokher

Segment part Offset part 0x9FFF:000F What does this number really mean? Address 0x9FFF0 + 0x 000F = 0x9FFFF 655,359 (0 to 655,359) or (1 to 655,360) or 1 to 640 Kb 0xFFFF:000F 0xFFFF0 + 0x 000F = 0xFFFFF 1 Mb = 1,048,576 Memory address space

Pointers are variables that contain memory addresses as their values. A variable name directly references to a value (direct addressing). A pointer indirectly references to a value. Referencing a value through a pointer is called indirection (indirect addressing). A value between 1 to 1,048,576 0xFFFF0 + 0x 000F = 0xFFFFF Segment Offset A pointer points to a memory location that contains the data 0xFFFFF 0xFFFFF 456

POINTERS DECLARATION What does float *b; meant?
Engineering H192 Winter 2005 POINTERS DECLARATION Examples of pointer declarations: int *a; float *b; char *c; The asterisk, in the declaration int *a;, tells the compiler that the variable a is a pointer type, meaning it contains an address (pointer) of a memory location that will contain an integer. What does float *b; meant? What does char *c; mean? Instructor: Pointers can be declared with regular variables in the same line, the asterisk (or lack of one) determines if the variable will contain an address or data. It is important to declare the correct type of pointer depending on the type of data it will point to. It is NOT possible to give a variable and pointer the same name. All variables (pointer or data) must still have a unique name. Narrator: Pointers are declared much like variables, except an asterisk must be before each variable name. Pointers can be declared with regular variables in the same line, the asterisk (or lack of one) determines if the variable will contain an address or data. It is important to declare the correct type of pointer depending on the type of data it will point to. It is NOT possible to give a variable and pointer the same name. All variables (pointer or data) must still have a unique name. address 0xFFFFF 0xFFFFF Content/value 456 Lecture 14

POINTERS Consider the statements: #include <stdio.h>
Engineering H192 Winter 2005 POINTERS Consider the statements: #include <stdio.h> int main ( ) { 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 */ aptr = &a ; bptr = &b ; What is the difference between int *aptr; and int a; declarations? 0xFFFFF 0xFFFFF Assign the address of a to the location at which aptr is pointing to. Lecture 14

float x; float *px; x = 6.5; px= &x; POINTERS
X is an address that would contain a float value Remember! The content of the memory location referenced by a pointer is obtained using the ``*'' operator (this is called dereferencing the pointer). Thus, *px refers to the value of x which is 6.5. 6.5 0xFFFFF px is a pointer to objects of type float meaning that it would contain an address of float type object If the address of x is 0xFFFFF then what would be assigned to px? Store the address of x into px

POINTERS Int x = 1, y = 2; Int *ip; ip= &x; y = *ip; *ip= 3;
We must associate a pointer to a particular data type. For example, we can't assign the address of a short int to a long int. Why? 0xFFFFF 0xFFFFE Int x = 1, y = 2; Int *ip; ip= &x; y = *ip; *ip= 3; 1 3 1 2 0xFFFFE What is wrong with float a, b; Int x, * p; p=&a;?

int*p, *q, x, y; p = &x; q = &y; *p = 10; *q = 20; p = q; *p = *q;
POINTERS int*p, *q, x, y; p = &x; q = &y; *p = 10; *q = 20; p = q; *p = *q; When a pointer is declared it does not point anywhere. We must set it to point somewhere before its use. The statements int*p; *p = 10; will generate an error. Why? 10 20

You can see the addresses of the data where in the memory they are loaded
{ char a; int b; float c; a=‘n’; b= 20; c= 20.5; printf (“%c is stored at address %u,\n”,a,&a); printf (“%d is stored at address %u,\n”,b,&b); printf (“%f is stored at address %u,\n”,c,&c); }

You can see the addresses of the data where in the memory they are loaded
{ int x, y, *p; X=10; p=&x; y=*p; printf (“value of x is %d is,\n”,x); printf (“%d is stored at address %u,\n”,x,&x); printf (“%d is stored at address %u,\n”,*&x,&x); printf (“%d is stored at address %u,\n”,*p, p); printf (“%d is stored at address %u,\n”, p, &p); printf (“%d is stored at address %u,\n”,y, &y); } Pinter address

POINTERS a=5; b=6.75; aptr = &a ; bptr = &b ;
Engineering H192 Winter 2005 POINTERS a=5; b=6.75; aptr = &a ; bptr = &b ; printf ("%d %d\n", aptr, bptr ) ; printf ("%d %f\n", *aptr, *bptr ) ; printf ("%d %f\n", a , b ) ; printf ( "%d %d\n", &a , &b ) ; return 0 ; } Instructor: The output of this program is simulated with two values from an input file and output given in the right column. The numbers representing addresses in this example would change if each student were to execute the program (each student would receive their own block of memory to use) and may also change during each execution of the program depending on if the operating system keeps the program cached after each use. Narrator: The output of this program is simulated with two values from an input file and output given in the right column. As expected, pointers and variables with address operators return the addresses of the a and b variables. Also the dereferenced pointers and variables themselves return the values of the variables. The numbers representing addresses in this example would change if you were to execute the program and may also change during each execution of the program depending on if the operating system keeps the program cached after each use Lecture 14

POINTERS double x = 3.14; *p = &x; p will be 3.14 3.14 Address of X
Setting pointer value to null int *p = 0; int *p = NULL; Set pointer value directly double x; *p = &x; *p = 3.14; Make sure pointer has been set to an allocated memory region printf(“%x”,p); Prints a hexadecimal number – the address that p points to For a pointer p, ++p and p++ are both equivalent to p + 1

You can see the addresses of the data where in the memory they are loaded
/*Program to illustrate the pointer expression and pointer arithmetic*/ #include< stdio.h > main() { int *p1,*p2; int a, b, x, y, z; a=30; b=6; p1=&a; p2=&b; x=*p1+ *p2 –6; y=6*- *p1/ *p2 +30; printf(“\n Address of a +%u”, p1); printf(“\n Address of b %u”, p2); printf(“\n a=%d, b=%d”, a, b); printf(“\n x=%d, y= %d”, x, y); p1=p1 + 70; p2= p2; printf(“\n a=%d, b=%d”,a,b); } Can Add or subtract integers from pointers. Can subtract one pointer from the other. Can use operators with the pointers p1+=; sum+=*p2; etc., Can use relational operators the expressions such as p1 >p2 , p1==p2 and p1!=p2

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.

Arithmetic Operations on Pointers

Review A variable is declared as int k;
A pointer variable is declared as int *p; we can get the address of a declared variable by using the unary & operator as in &k. We can "dereference" a pointer, i.e. refer to the value of that which it points to, by using the unary '*' operator as in *ptr. Pointer operators: * dereferences a pointer, & creates a pointer (reference to) An "lvalue" of a variable is the value of its address, i.e. where it is stored in memory. The "rvalue" of a variable is the value stored in that variable (at that address).

Pointers to Referencing & Derefrencing
int x, *y, z, *q; x = 3; y = &x; // y points to x printf("%d\n", x); // outputs 3 printf("%d\n", y); // outputs x’s address, will seem like a random number to us printf("%d\n", *y); // outputs what y points to, or x (3) printf("%d\n", *y+1); // outputs 4 (print out what y points to + 1) printf("%d\n", *(y+1)); // this outputs the item after x in memory – what is it? z = *(&x); // z equals 3 (what &x points to, which is x) q = &*y; // q points to 3 – note *& and &* cancel out

Pointers to Arrays int x = 1, y = 2, z[10]; int *ip; // ip is a pointer to an int, so it can point to x, y, or an element of z ip = &x; // ip now points at the location where x is stored y = *ip; // set y equal to the value pointed to by ip, or y = x *ip = 0; // now change the value that ip points to to 0, so now x = 0 // but notice that y is unchanged ip = &z[0]; // now ip points at the first location in the array z *ip = *ip + 1; // the value that ip points to (z[0]) is incremented You can interact with the array elements either through pointers or by using z[ index]

Using Pointers with Arrays
ip = &z[0]; sets pointer ip to point at the first element of the array In fact, z is a pointer as well and we can access z[0] either using z[0], *ip, or *z What about accessing z[1]? We can do z[1] as usual, or we can add 1 to the location pointed to by ip or z, that is *(ip+1) or *(z+1) While we can reset ip to be ip = ip+1, we cannot reset z to be z = z+1 adding 1 to ip will point to z[1], but if z = z + 1 were legal, we would lose access to the first array location since z is our array variable Notice that ip=ip+1 (or ip++) moves the pointer 4 bytes instead of 1 to point at the next array location if the array were an array of doubles, the increment would move ip to point 8 bytes away, if the array were chars, then ip would be 1 byte further Increment depends on the size (in bytes) of the object to which a pointer is pointing at.

Iterating Through the Array
Here we see two ways to iterate through an array, the usual way, but also a method using pointer arithmetic int j; for(j = 0; j < n; j++) a[j]++; int *pj; for(pj = a; pj < a + n; pj++) (*pj)++; Let’s consider the code on the right: pj is a pointer to an int We start with pj pointing at a, that is, pj points to a[0] The loop iterates while pj < a + n pj is a pointer, so it is an address a is a pointer to the beginning of an array of n elements so a + n is the size of the array pj++ increments the pointer to point at the next element in the array The instruction (*pj)++ says “take what pj points to and increment it” NOTE: (*pj)++; increments what pj points to, *(pj++); increments the pointer to point at the next array element what do each of these do? *pj++; *pj; Do the following: int a[ ] = {1, 5}; int *p = a; printf(“%d\n”, *p++); printf(“%d\n”, *p); p = a; printf(“%d\n”, *++p); printf(“%d\n”, ++*p); And see what you get. Which of these increment p vs increment *p? *p++, ++*p, *++p??? Using *p++ is dangerous unless you are clear in what you are doing.

Array Example Using a Pointer
int x[4] = {12, 20, 39, 43}, *y; y = &x[0]; // y points to the beginning of the array printf("%d\n", x[0]); // outputs 12 printf("%d\n", *y); // also outputs 12 printf("%d\n", *y+1); // outputs 13 (12 + 1) printf("%d\n", (*y)+1); // also outputs 13 printf("%d\n", *(y+1)); // outputs x[1] or 20 y+=2; // y now points to x[2] printf("%d\n", *y); // prints out 39 *y = 38; // changes x[2] to 38 printf("%d\n", *y-1); // prints out x[2] - 1 or 37 *y++; // sets y to point at the next array element printf("%d\n", *y); // outputs x[3] (43) (*y)++; // sets what y points to to be 1 greater printf("%d\n", *y); // outputs the new value of x[3] (44)

Strings There is no string type in C, strings are arrays of chars
char str[10]; // str is an array of 10 chars or a string char *str; // str points to the beginning of a string of unspecified length There is a string.h library with numerous string functions they all operate on arrays of chars and include: strcpy(s1, s2) – copies s2 into s1 (including ‘\0’ as last char) strncpy(s1, s2, n) – same but only copies up to n chars of s2 strcmp(s1, s2) – returns a negative int if s1 < s2, 0 if s1 = = s2 and a positive int if s1 > s2 strncmp(s1, s2, n) – same but only compares up to n chars strcat(s1, s2) – concatenates s2 onto s1 (this changes s1, but not s2) strncat(s1, s2, n) – same but only concatenates up to n chars strlen(s1) – returns the integer length of s1 strchr(s1, ch) – return a pointer to the first occurrence of ch in s1 (or NULL if ch is not present) strrchr(s1, ch) – same but the pointer points to the last occurrence of ch strpbrk(s1, s2) – return a pointer to the first occurrence of any character in s1 that matches a character in s2 (or NULL if none are present) strstr(s1, s2) – substring, return a pointer to the char in s1 that starts a substring that matches s2, or NULL if the substring is not present string = s; The variable string is merely a pointer whereas s is an array. string, prior to doing string=s had nothing to point to and therefore could not be operated upon. s on the other hand was allocated memory when s was created. We learn how to allocate memory for strings in C chapter 6 by using calloc. For now, just use arrays to declare strings.

Implementing Some of These
void strcpy(char *s, char *t) { int i = 0; while((s[i] = t[i]) != ‘\0’) i++;} } int strlen(char *s) { int n; for(n = 0; *s != ‘\0’; s++) n++; return n; } int strcmp(char *s, char *t) { int i; for(i=0;s[i] = = t[i];i++) if(s[i] = = ‘\0’) return 0; return s[i] – t[i]; } strcpy(s1, s2) strlen(s1) strcmp(s1, s2) void strcpy(char *s, char *t) { while((*s = *t) != ‘\0’) s++; t++; } int strcmp(char *s, char *t) { for( ; *s = = *t; s++, t++) if(*s = = ‘\0’) return 0; return *s - *t; } Notice in the second strcmp and second and third strcpy the use of pointers to iterate through the strings. The conciseness of the last strcmp and strcpy make them hard to understand Notice that these functions receive parameters of type char * instead of arrays. Why? Recall that C uses pass-by-copy, so what is copied from the calling function to the called function is a pointer to the string array. We could also implement these with parameters of type char s[ ] if we prefer, but using *s is closer to what is really happening. The parameter is a pointer into an array. Now, for any of these functions to work, we must assume that the last character in any string is ‘\0’. This is automatically inserted for us if we input the array using scanf, or if we directly assign the array to a string when declared, as in char string[ ] = “hello”; However, the ‘\0’ is not inserted if we do this: char notAString[ ] = {‘h’, ‘e’, ‘l’, ‘l’, ‘o’}; Because, in this case, the variable is thought of as a true char array. strcmp(s1, s2) strccpy(s1, s2) void strcpy(char *s, char *t) { while((*s++ = *t++) != ‘\0’); } Check it copies t[i] into s[i] and checks for NULL strcpy(s1, s2)

More On Pointer Arithmetic
Got to the first element We can also perform subtraction on pointers Here, we pass to a function the address of the third element of an array (&a[2]) and use pointer subtraction to get to a[0] and a[1]) Decrease pointer by 1 Start with the 10th element int a[10] = {…}; int *ip; for(ip = &a[9]; ip >= a; ip--) ip = &a[2]; Functions addmem int addem(int *ip) { int temp; temp = *ip + *(ip – 1) + *(ip – 2); return temp; } int a[3] = {…}; printf(“%d”, addem(&a[2])); Recall: a[0] = *a and a[i] = *(a + i) If a is an array, and p = &a[0] then we can reference array elements as a[i], *(p+i), but we can also reference them as p[i] and *(a+i) – that is, a and p are both pointers to the array And can be dereferenced by * or by [ ]

Multidimensional Arrays
C allows multidimensional arrays Example: int matrix[5][10]; Some differences: Because functions can be compiled separately, we must denote all but one dimension of a multiple dimensional array in a function’s parameter list void afunction (int amatrix[ ][10]); Because arrays are referenced through pointers, there are multiple ways to declare and access 2+ dimensional arrays This will be more relevant when dealing with an array of strings (which is a 2-D array) int *a[3]; // array of 3 pointers int x[2] = {1, 2}; int y[3] = {3, 4, 5}; int z[4] = {6, 7, 8, 9}; *a = &x[0]; // a[0] points to x[0] *(a+1) = &y[0]; // a[1] points to y[0] *(a+2) = &z[0]; // a[2] points to z[0] // array a is a jagged array, it is not // rectangular, or of equal dimensions int a[10][20]; int *a[10]; int **a; We discuss mapping functions in CSC 507, but here is a bit of information. The compiler sets up a mapping function so that the array access a[i] or b[i][j] Can be translated into a memory location. This makes array accesses efficient. Without a mapping function, the actual memory location for an array reference like b[i][j] would have to be determined at run-time. Usually, computing a mapping function is straight-forward for a compiler. But because a C function might be in a file that does not include the array’s declaration, the compiler still must know what the array’s dimensions are to set up the mapping function. The only dimension not necessary is the number of rows (the first dimension). Therefore, the following are required in either a prototype that defines a function, or in the array’s header: int a[ ] // one dimension, no other values needed int b[ ][10] // two dimensions, number of rows not needed int c[ ][10][20][30] // four dimensions, number of rows not needed *a[4] –first element of 5th array element *a[9] –first element of 10th array element **a –first element of a[0]

Pointers to Pointers As indicated in the last slide, we can have an array of arrays which is really an array of pointers or pointers to pointers We may wish to use pointers to pointers outside of arrays as well, although it is more common that pointers to pointers represent array of pointers Consider the following: int a; int *p; int **q; a = 10; p = &a; q = &p; printf(“%d”, **q); // outputs 10 We dereference our pointer p with *p but we dereference our pointer to a pointer q with **q *q is actually p, so **q is a 10 Address of a Address of p

Arrays of Strings Implementation
We could implement an array of strings as a 2-D array of chars char array[10][10]; This has two disadvantages All strings will be 10 chars long Requires 2 nested for-loops for most operations such as string comparison or string copying, which can become complicated Instead, we will implement our array of strings as an array of pointers char *array[10]; Each pointer points to one string Follow the string through the pointer Go to the next string using a for-loop Because strcpy, strcmp, strlen all expect pointers, we can use these by passing an array element (since each array element is a pointer to a string)

Example char *x[ ] = {"hello\0", "goodbye\0", "so long\0", "thanks \0"}; // our array of strings x is a set of 4 pointers char *y; // let y be a pointer to a char so it can be used to move through a single string int i; for(i=0;i<4;i++) // iterate for each string in x { y = x[i]; // x[i] is an array, x is really a pointer, so this sets y to x’s starting addr. while(*y!='\0') // while the thing y points to is not the end of a string printf("%c", *y); // print what y points to y++; // and go on to the next char in x } printf("\n"); // separate strings in output with \n X[0] hello NULL X[1] goodbye X[2] So long X[3] thanks Notice that if we had used char x[ ][ ] = {…}; then the storage space would have been 4 strings of length 23 (the length of the longest string) or 92 bytes instead of 42 bytes as it is above

Passing Arrays Because you can compile functions separately, the compiler must be able to “know” about an array being passed in to a function, so you must specify all (or most) of the definition: The type and all dimensions except for the first When an array is passed to a function, what is being passed is a pointer to the array In the formal parameter list, you can either specify the parameter as an array or a pointer int array[100]; afunction(array); void afunction(int *a) {…} or void afunction(int a[ ]) {…} The reason that the compiler must “know” about the array dimensions is to set up a mapping function. A mapping function is generated by the compiler so that, at run time, the operation a[i][j] can be converted into a memory location access easily. The mapping function for an array of N rows and M columns looks like this in C: a[i][j] = OFFSET + i * M + j Where OFFSET is the starting location for a. See if you can figure out why the formula is as it is. But notice that while we need to know M (number of columns), we don’t need N (number of rows). Therefore, when you pass the array to a function, you must specify the number of columns but not the number of rows. We study this in more detail in CSC 507. int array[5][10][15]; afunction(array); void afunction(int a[ ][10][15]) {…} or void afunction(int *a[10][15]) {…} or void afunction(int a[5][10][15]) {…} or void afunction(int **a[15]) {…} etc

In functions, do not return p; where p is a pointer Recall local variables are deallocated when the function ends so whatever p is pointing to will no longer be available but if you return the pointer, then you still are pointing at that memory location even though you no longer know what is there We can declare a pointer to point to a void type, which means that the pointer can point to any type However, this does require a cast before the pointer can be assigned int x; float y; void *p; // p can point to either x or y p = (int *) &x; // p can point to int x once the address is cast p = (float *) &y; // or p can point to float y Pointers that don’t currently point to anything have the special value NULL and can be tested as (p = = NULL) or (!p), and (p != NULL) or (p)

Pointers and Structures
struct tag { char lname[20]; /* last name */ char fname[20]; /* first name */ int age; /* age */ float rate; /* e.g per hour */ }; struct tag my_struct; /* declare the structure my_struct */ int main(void) { strcpy(my_struct.lname,"Jensen"); strcpy(my_struct.fname,"Ted"); printf("\n%s ",my_struct.fname); printf("%s\n",my_struct.lname); return 0; } It will copy the last name and the first name into the structure Passing structure takes more memory (stack space) , aThe pointer uses a minimum amount of stack space.

Pointers and Structures
struct tag{ /* the structure type */ char lname[20]; /* last name */ char fname[20]; /* first name */ Int age; /* age */ float rate; /* e.g per hour */ }; struct tag my_struct; /* define the structure */ void show_name(struct tag *p); /* function prototype */ int main(void) { struct tag *st_ptr; /* a pointer to a structure */ st_ptr = &my_struct; /* point the pointer to my_struct */ strcpy(my_struct.lname,"Jensen"); strcpy(my_struct.fname,"Ted"); printf("\n%s ",my_struct.fname); printf("%s\n",my_struct.lname); my_struct.age = 63; show_name(st_ptr); /* pass the pointer */ return 0; } void show_name(struct tag *p) { printf("\n%s ", p->fname); /* p points to a structure */ printf("%s ", p->lname); printf("%d\n", p->age);

Pointers and Structures
struct tag{ /* the structure type */ char lname[20]; /* last name */ char fname[20]; /* first name */ Int age; /* age */ float rate; /* e.g per hour */ }; struct tag my_struct; /* define the structure */ struct tag *st_ptr; Lname [20 Fname [20] age rate An instance of tag in memory, also called instantiation st_ptr = &my_struct; Access a member by de-referencing the pointer. Address of my struct (*st_ptr).age = 63; OR st_ptr -> age = 63;

Pointers to Functions A function that is capable of sorting virtually any collection of data that can be stored in an array. The data might be an array of strings, or integers, or floats, or even structures. The sorting algorithm can be the same for all.

Pointers to Functions int arr[10] = { 3,6,1,2,3,8,4,1,7,2};
void bubble(int a[], int N); int main(void) { int i; putchar('\n'); for (i = 0; i < 10; i++) printf("%d ", arr[i]); } bubble(arr,10); return 0; void bubble(int a[], int N) { int i, j, t; for (i = N-1; i >= 0; i--) for (j = 1; j <= i; j++) if (a[j-1] > a[j]) t = a[j-1]; a[j-1] = a[j]; a[j] = t; } SORTING AN ARRAY OF INTEGERS

Pointers to Functions void bubble(int *p, int N) { int i, j, t;
for (i = N-1; i >= 0; i--) for (j = 1; j <= i; j++) { if (compare(&p[j-1], &p[j])) t = p[j-1]; p[j-1] = p[j]; p[j] = t; } int arr[10] = { 3,6,1,2,3,8,4,1,7,2}; void bubble(int *p, int N); int compare(int *m, int *n); int main(void) { int i; for (i = 0; i < 10; i++) { printf("%d ", arr[i]); } bubble(arr,10); { printf("%d ", arr[i]); return 0; m=&p[j-1], n=&p[j], int compare(int *m, int *n) { return (*m > *n); } SORTING AN ARRAY OF INTEGERS BUT IN THIS COMPARISON Is DONE BY A FUNCTION

Pointers to Functions void bubble(int *p, int N)
{ int i, j, t; for (i = N-1; i >= 0; i--) { for (j = 1; j <= i; j++) { if (compare((void *)&p[j-1], (void *)&p[j])) { t = p[j-1]; p[j-1] = p[j]; p[j] = t; } int arr[10] = { 3,6,1,2,3,8,4,1,7,2}; void bubble(int *p, int N); int compare(void *m, void *n); int main(void) { int i; for (i = 0; i < 10; i++) { printf("%d ", arr[i]); } bubble(arr,10); return 0; } Bubble sort or any program can be made general by identifying the code that can be made general. For example by making the compare function or swapping operations general the same bubble sort can be used for different data types. int compare(void *m, void *n) { int *m1, *n1; m1 = (int *)m; n1 = (int *)n; return (*m1 > *n1);}

Pointers to a Function Remember the difference
The function name translates into an address of that function in the code segment. Declaration like int (*fptr)(const void *p1, const void *p2); indicates that we are declaring a function pointer. Pass a pointer to a function as a parameter Declaration int *fptr (const void *p1, const void *p2); indicates that we are declaring a function that will return a pointer to an integer type. void bubble(void *p, int width, int N, int(*fptr)(const void *, const void *)); int compare_string(const void *m, const void *n); int compare_long(const void *m, const void *n); int compare_string(const void *m, const void *n) { char *m1 = (char *)m; char *n1 = (char *)n; return (strcmp(m1,n1)); } Int main (void){ /* in the caller origram */ ……. bubble(arr, 4, 10, compare_long); /* sort the longs */ bubble(arr2, 20, 5, compare_string); } int compare_long(const void *m, const void *n) { long *m1, *n1; m1 = (long *)m; n1 = (long *)n; return (*m1 > *n1); }

Pointers and Dynamic Allocation of Memory
What is compile time allocation? What is run time allocation? Allocate memory at run time using malloc(), calloc() Return a pointer to the first byte of the allocated block. The ANSI compiler return void type pointer int *iptr; iptr = (int *) malloc(10 * sizeof (int)); if (iptr == NULL) { …. Error….} for (k = 0; k < 10; k++) Iptr [k] = 2; Allocates 10 memory locations to store the 10 integers. Access the allocated locations #define COLS 5 typedef int RowArray[COLS]; RowArray *rptr; int main(void) { int nrows = 10; int row, col; rptr = malloc(nrows * COLS * sizeof(int)); for (row = 0; row < nrows; row++) { for (col = 0; col < COLS; col++) { rptr[row][col] = 17;}} return 0;} Explain