We can use pointers to request memory on the fly at runtime.
malloc(): Allocate block of memory.free(): Deallocate that block of memory.freeing it (to avoid accidentally dereferencing a junk value).Note: Check after allocation that memory was indeed allocated.
- Done by seeing if your pointer points to a valid memory location instead of NULL.
#include <stdio.h>
#include <stdlib.h>
int main() {
int n, *ptr = 0;
// Prompt user for array length
printf("Enter number of elements: ");
scanf("%d", &n);
// Dynamic memory allocation using malloc()
ptr = malloc(n*sizeof(int));
// Exit if no memory was allocated
if(ptr == NULL)
{
printf("\nError! Memory not allocated\n");
return 0;
}
// Prompt user for array elements
printf("\nEnter elements of array: \n");
for(int i = 0; i < n; i++) {
scanf("%d", ptr+i);
}
// Printing the array elements
printf("\nThe elements of the array are: ");
for(int i = 0; i < n; i++) {
printf("%d ",ptr[i]); // ptr[i] is same as *(ptr + i)
}
// Deallocate the block of memory
free(ptr);
// Print newline and return
puts("");
return 0;
}malloc() returns a void pointer, ptr = malloc(n*sizeof(int)); automatically promotes it to an int pointer.ptr = (int *) malloc(n*sizeof(int));Pointer to a Pointer: Declared with two * symbols.
int main() {
int a = 10;
int *p1 = &a;
int **p2 = &p1;
printf("&a : Ox%u\n", &a);
printf("&p1: Ox%u\n", &p1);
printf(" - *p1: %d\n", *p1);
printf("&p2: Ox%u\n", &p2);
printf(" - *p2 : %u (garbage)\n", *p2);
printf(" - **p2: %d\n", **p2);
return 0;
}Example Output:
&a : Ox278518276
&p1: Ox278518280
- *p1: 10
&p2: Ox278518288
- *p2 : 278518276 (garbage)
- **p2: 10A multidimensional array can be thought of as an array of arrays.
**array)
dynamically without bracket notion.#include <stdio.h>
#include <stdlib.h>
int main()
{
int **array;
int row, col;
printf("Give me rows and columns: \n");
scanf("%d%d", &row, &col);
// Allocate memory for the 1D array.
// - Note how we are doing sizeof(int *), not sizeof(int)!
array = malloc(row * sizeof(int *));
if (array == NULL)
{
printf("out of memory\n");
exit(1);
}
// Allocate memory for the rest of the 2D array.
for (int i = 0; i < row; i++)
{
*(array+i) = malloc(col * sizeof(int));
if(array[i] == NULL)
{
printf("out of memory\n");
exit(1);
}
}
// Assign values and print contents of array
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
{
*(*(array+i)+j) = i;
// ^ Same thing as array[i][j] = i;
printf("%d \t", *(*(array+i)+j));
}
printf("\n");
}
// Deallocate the array and exit
for (int i = 0; i < row; i++)
{
free(*(array+i));
}
free(array);
array = NULL;
return 0;
}Instructions: Read each piece of code and determine the output of each numbered section.
- (Code with answers is provided below the uncommented code)
Question: Pointer Arithmetic
#include <stdio.h> int main() { int *p; int sample[3] = { -1, 6, 5 }; // I. p = sample; printf("%d\n", *p); // II. *p = *(p)*3; printf("%d\n", *p); // III. p = ++p; printf("%d\n", *p); // IV. p = p++; printf("%d\n", *p); // V. *p = *(p - 1); printf("%d\n", *p); // VI. ++(*p); printf("%d\n", *p); }#include <stdio.h> int main() { int *p; int sample[3] = { -1, 6, 5 }; // I. Prints "-1" p = sample; printf("%d\n", *p); // II. Prints "-3" (-1 x 3) *p = *(p)*3; printf("%d\n", *p); // III. Prints "6" (pre-incremented returns x+1) p = ++p; printf("%d\n", *p); // IV. Prints "6" (post-incremented returns x) p = p++; printf("%d\n", *p); // V. Prints "-3" *p = *(p - 1); printf("%d\n", *p); // VI. Prints "-2" (-3 + 1) ++(*p); printf("%d\n", *p); }
Question: Pointer Confusion
#include <stdio.h> #include <stdlib.h> int main() { int *x, *y, *z, *a, b[3] = {-4, 5, -6}; a = malloc(3 * sizeof(int)); x = a; for (int k = 1; k < 4; k++) a[k - 1] = k; // I. printf("%d\t%d\t%d\n", a[0], a[1], a[2]); z = &b[2]; y = (++x) + 1; *x = *x + 4; // II. printf("%d\t%d\t%d\n", *x, *y, *z); *(--z) = *(y - 1) + *x; *(z + 1) = *(x + 1) - 3; // III. printf("%d\n", *z); *y-- = (*++z) - (*&a[2]); // IV. printf("%d\n", *y); // V. printf("%d\n", *x + 2); for (int j = 0; j < 3; j++) { // VII. printf("%d\t%d\n", a[j], b[j]); } free(a); a = NULL; return 0; }#include <stdio.h> #include <stdlib.h> int main() { int *x, *y, *z, *a, b[3] = {-4, 5, -6}; a = malloc(3 * sizeof(int)); x = a; for (int k = 1; k < 4; k++) a[k - 1] = k; // I. 1 2 3 printf("%d\t%d\t%d\n", a[0], a[1], a[2]); z = &b[2]; y = (++x) + 1; *x = *x + 4; // II. 6 3 -6 printf("%d\t%d\t%d\n", *x, *y, *z); *(--z) = *(y - 1) + *x; *(z + 1) = *(x + 1) - 3; // III. 12 printf("%d\n", *z); *y-- = (*++z) - (*&a[2]); // IV. 6 printf("%d\n", *y); // V. 8 printf("%d\n", *x + 2); for (int j = 0; j < 3; j++) { // VII. 1 -4 // 6 12 // -3 0 printf("%d\t%d\n", a[j], b[j]); } free(a); a = NULL; return 0; }
void *malloc(size_t size);
malloc: int *x = malloc(100);void *calloc(size_t nmemb, size_t size);
malloc()calloc: int *x = calloc(0, sizeof(int));void free(void *_Nullable ptr);Example
free: free(x);
void *realloc(void *_Nullable ptr, size_t size);
void *reallocarray(void *_Nullable ptr, size_t nmemb, size_t size);
relloc will attempt to assign a new block of memory and copy the old block contents.realloc#include <stdio.h>
#include <stdlib.h>
int main () {
char *str;
str = (char *) malloc(15);
strcpy(str, "Hello, How are");
printf("String = %s, Address = %p\n", str, str);
str = realloc(str, 20);
strcat(str, " you?");
printf("String = %s, Address = %p\n", str, str);
free(str);
return(0);
}