Basics of Character Double Pointers

In this section, you are going to learn

  • Step 1 : Define a character

char c = 65;
  • Step 2 : Define a Single Pointer

char *sp = &c;

OR

char *sp;

sp = &c;
  • Step 3 : Define a Double Pointer

char **dp = &sp;

OR

char **dp;

dp = &sp;
  • Step 4 : Access user data (in this case character) using single pointer

printf("c = %d\n", *sp);
  • Step 5 : Access user data (in this case character) using double pointer

printf("c = %d\n", **dp);
  • Step 6 : Use *dp to point to new user data (in this case variable d)

*dp = &d;

Remember below equations

  • dp = &sp

  • *dp = sp

  • *dp = &c

  • Hence changing *dp changes sp as well

  • Step 7 : Now user data can be accessed using *sp, **dp which prints value of character d

printf("d = %d\n", d);
printf("d = %d\n", *sp);
printf("d = %d\n", **dp);
  • See full program below

#include <stdio.h>

int main(void)
{
        char c = 65;
        char *sp = &c;
        char **dp = &sp;

        printf("c = %d\n", c);
        printf("*sp = %d\n", *sp);
        printf("**dp = %d\n", **dp);

        char d = 100;

        *dp = &d;

        printf("d = %d\n", d);
        printf("*sp = %d\n", *sp);
        printf("**dp = %d\n", **dp);

        return 0;
}
  • Output is as below

c = 65
*sp = 65
**dp = 65

d = 100
*sp = 100
**dp = 100
  • Step 1 : Define a single dimension array of characters

char arr[] = "Laptop";
  • Step 2 : Define a single pointer

char *sp = arr;

OR

char *sp;

sp = arr;

OR

char *sp;

sp = &arr[0];
  • Step 3 : Define a double pointer

char **dp = &sp;

OR

char **dp;

dp = &sp;
  • Step 4 : Access user data (in this case array of characters) using single pointer variable sp

printf("arr = %s\n", sp);
  • Step 5 : Access user data (in this case array of characters) using double pointer variable dp

printf("arr = %s\n", *dp);

Note *dp should be called as single pointer because of below equations

  • dp = &sp;

  • *dp = sp;

  • See full program below

#include <stdio.h>

int main(void)
{
        char arr[] = "Laptop";
        char *sp = arr;
        char **dp = &sp;

        //Access full array
        printf("arr = %s\n", arr);
        printf("sp = %s\n", sp);
        printf("*dp = %s\n", *dp);

        //Access individual character
        printf("arr[3] = %c\n", arr[3]);
        printf("sp[3] = %c\n", sp[3]);
        printf("(*dp)[3] = %c\n", (*dp)[3]);

        return 0;
}
  • Output is as below

arr = Laptop
sp = Laptop
*dp = Laptop

arr[3] = t
sp[3] = t
(*dp)[3] = t
  • Step 1 : Define a single pointer

char *sp;
  • Step 2 : Allocate heap memory to single pointer

sp = malloc(10 * sizeof(char));
  • Step 3 : Copy User data to heap memory

strcpy(sp, "Laptop");
  • Step 4 : Define a double pointer

char **dp;
dp = &sp;
  • Step 5 : Access User data using single pointer variable sp

printf("arr = %s\n", sp);
printf("arr[3] = %c\n", sp[3]);
  • Step 6 : Access User data using double pointer variable dp

printf("arr = %s\n", *dp);
printf("arr[3] = %c\n", (*dp)[3]);
  • See full program below

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(void)
{
        char *sp;

        sp = malloc(10 * sizeof(char));
        strcpy(sp, "Laptop");

        char **dp;
        dp = &sp;

        //Access full array
        printf("arr = %s\n", sp);
        printf("arr = %s\n", *dp);

        //Access individual character
        printf("arr[3] = %c\n", sp[3]);
        printf("arr[3] = %c\n", (*dp)[3]);

        free(sp);

        return 0;
}
  • Output is as below


  • Step 1 : Define a double pointer

char **dp;
  • Step 2 : Allocate memory to a double pointer

dp = malloc(sizeof(char *));
  • Step 3 : Allocate memory to a single pointer

*dp = malloc(sizeof(char));
  • Step 4 : Store user data

**dp = 65;
  • Step 5 : Read user data

printf("User data = %d\n", **dp);
  • Step 6 : Free memory in opposite flow of allocation

free(*dp);

free(dp);
  • See full program below

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main(void)
{
        char **dp;

        dp = malloc(sizeof(char *));

        *dp = malloc(sizeof(char));

        **dp = 65;

        printf("User data = %d\n", **dp);

        free(*dp);

        free(dp);

        return 0;
}
  • Step 1 : Define a double pointer

char **dp;
  • Step 2 : Allocate memory to a double pointer

dp = malloc(sizeof(char *));
  • Step 3 : Allocate memory to a single pointer

*dp = malloc(10 * sizeof(char));
  • Step 4 : Copy User data to heap

strcpy(*dp, "Laptop");
  • Step 5 : Read user data from heap

printf("User data = %s\n", *dp);

for (int i = 0; i < 10; i++) {
        printf("User data = %c\n", (*dp)[i]);
}
  • Step 6 : Free memory in opposite flow of allocation

free(*dp);

free(dp);
  • See full program below

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main(void)
{
        char **dp;

        dp = malloc(sizeof(char *));

        *dp = malloc(10 * sizeof(char));
        memset(*dp, 0, 10);

        strcpy(*dp, "Laptop");

        printf("User data = %s\n", *dp);

        for (int i = 0; i < 10; i++) {
                printf("User data = %c\n", (*dp)[i]);
        }

        free(*dp);

        free(dp);

        return 0;
}
  • Step 1 : Define 3 Single dimension character arrays

char arr0[32] = "Laptop";
char arr1[32] = "Mouse";
char arr2[32] = "Keyboard";
  • Step 2 : Define array of single pointers

char *sp_arr[] = {arr0, arr1, arr2};
  • Step 3 : Define a double pointer

char **dp;

dp = sp_arr;
  • Step 4 : Use dp to change contents of single dimension arrays

strcpy(dp[0], "New Laptop");
strcpy(dp[1], "New Mouse");
strcpy(dp[2], "New Keyboard");
  • Step 5 : Use sp_arr to access contents of single dimension arrays

printf("arr0 = %s\n", sp_arr[0]);
printf("arr1 = %s\n", sp_arr[1]);
printf("arr2 = %s\n", sp_arr[2]);
  • Step 6 : Use dp to access contents of single dimension arrays

printf("arr0 = %s\n", dp[0]);
printf("arr1 = %s\n", dp[1]);
printf("arr2 = %s\n", dp[2]);
  • See full program below

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(void)
{
        char arr0[32] = "Laptop";
        char arr1[32] = "Mouse";
        char arr2[32] = "Keyboard";

        char *sp_arr[] = {arr0, arr1, arr2};

        char **dp;

        dp = sp_arr;

        strcpy(dp[0], "New Laptop");
        strcpy(dp[1], "New Mouse");
        strcpy(dp[2], "New Keyboard");

        printf("arr0 = %s\n", sp_arr[0]);
        printf("arr0 = %s\n", dp[0]);

        printf("arr1 = %s\n", sp_arr[1]);
        printf("arr1 = %s\n", dp[1]);

        printf("arr2 = %s\n", sp_arr[2]);
        printf("arr2 = %s\n", dp[2]);

        return 0;
}
  • Step 1 : Define a double pointer

char **dp;
  • Step 2 : Allocate heap memory : Create 3 single pointers dp[0], dp[1], dp[2]

dp = malloc(3 * sizeof(char *));
  • Step 3 : Allocate heap memory : Create 3 single dimension character arrays of size 32 characters each

dp[0] = malloc(32 * sizeof(char));
dp[1] = malloc(32 * sizeof(char));
dp[2] = malloc(32 * sizeof(char));
  • Step 4 : Store user data

strcpy(dp[0], "New Laptop");
strcpy(dp[1], "New Mouse");
strcpy(dp[2], "New Keyboard");
  • Step 5 : Access user data

printf("string 0 = %s\n", dp[0]);
printf("string 1 = %s\n", dp[1]);
printf("string 2 = %s\n", dp[2]);
  • Step 6 : Free 3 character arrays

free(dp[0]);
free(dp[1]);
free(dp[2]);
  • Step 7 : Free 3 single pointers

free(dp);
  • See full program below

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(void)
{
        char **dp;

        dp = malloc(3 * sizeof(char *));
        dp[0] = malloc(32 * sizeof(char));
        dp[1] = malloc(32 * sizeof(char));
        dp[2] = malloc(32 * sizeof(char));

        strcpy(dp[0], "New Laptop");
        strcpy(dp[1], "New Mouse");
        strcpy(dp[2], "New Keyboard");

        printf("string 0 = %s\n", dp[0]);
        printf("string 1 = %s\n", dp[1]);
        printf("string 2 = %s\n", dp[2]);

        free(dp[0]);
        free(dp[1]);
        free(dp[2]);

        free(dp);

        return 0;
}
  • In this example,

    • Programmer is defining a function called fun which takes care of allocation

    • Plans to use the allocated memory in function main

    • But pointer dp is passed by value to function fun
      • Which means there are two pointers, dp and dp_v

      • Any assignement done to dp_v will not affect dp in caller

    • Hence, below program crashes inside function main when first strcpy is tried

  • See full program below

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void fun(char **dp_v)
{
        dp_v = malloc(3 * sizeof(char *));
        dp_v[0] = malloc(32 * sizeof(char));
        dp_v[1] = malloc(32 * sizeof(char));
        dp_v[2] = malloc(32 * sizeof(char));
}

int main(void)
{
        char **dp;

        fun(dp);

        strcpy(dp[0], "New Laptop");
        strcpy(dp[1], "New Mouse");
        strcpy(dp[2], "New Keyboard");

        printf("dp[0] = %s\n", dp[0]);
        printf("dp[1] = %s\n", dp[1]);
        printf("dp[2] = %s\n", dp[2]);

        free(dp[0]);
        free(dp[1]);
        free(dp[2]);

        free(dp);

        return 0;
}
  • In order to fix the problem mentioned in above case, let us pass double pointer by reference

  • Step 1 : Define a double pointer

char **dp;
  • Step 2 : Pass double pointer by reference

fun(&dp);
  • Step 3 : Allocate memory inside function fun

void fun(char ***dp_r)
{
        *dp_r = malloc(3 * sizeof(char *));
        (*dp_r)[0] = malloc(32 * sizeof(char));
        (*dp_r)[1] = malloc(32 * sizeof(char));
        (*dp_r)[2] = malloc(32 * sizeof(char));
}
  • Step 4 : Use single pointers dp[0], dp[1], dp[2] in caller to store user data

strcpy(dp[0], "New Laptop");
strcpy(dp[1], "New Mouse");
strcpy(dp[2], "New Keyboard");
  • Step 5 : Use single pointers dp[0], dp[1], dp[2] in caller to access user data

printf("dp[0] = %s\n", dp[0]);
printf("dp[1] = %s\n", dp[1]);
printf("dp[2] = %s\n", dp[2]);
  • Step 6 : Free 3 arrays of characters after use

free(dp[0]);
free(dp[1]);
free(dp[2]);
  • Step 7 : Free 3 Single pointers after use

free(dp);
  • See full program below

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void fun(char ***dp_r)
{
        *dp_r = malloc(3 * sizeof(char *));
        (*dp_r)[0] = malloc(32 * sizeof(char));
        (*dp_r)[1] = malloc(32 * sizeof(char));
        (*dp_r)[2] = malloc(32 * sizeof(char));
}

int main(void)
{
        char **dp;

        fun(&dp);

        strcpy(dp[0], "New Laptop");
        strcpy(dp[1], "New Mouse");
        strcpy(dp[2], "New Keyboard");

        printf("dp[0] = %s\n", dp[0]);
        printf("dp[1] = %s\n", dp[1]);
        printf("dp[2] = %s\n", dp[2]);

        free(dp[0]);
        free(dp[1]);
        free(dp[2]);

        free(dp);

        return 0;
}