There are two way of working with array of characters (strings) in C. They are as follows:

char a[ROW][COL];
char *b[ROW];

Pictorial representation is available as an inline comment in the code.

Based on how you want to represent the array of characters (strings), you can define pointer to that as follows

    char (*ptr1)[COL] = a;
    char **ptr2 = b;

They are fundamentally different types (in a subtle way) and so the pointers to them is also slightly different.

The following example demonstrates the different ways of working with strings in C and I hope it helps you in better understanding of array of characters (strings) in C.

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

#define ROW 5
#define COL 10

int main(void) 
{
    int i, j;
    char a[ROW][COL] = {"string1", "string2", "string3", "string4", "string5"};
    char *b[ROW];

    /*

    a[][]

      0   1   2   3   4   5   6     7    8   9
    +---+---+---+---+---+---+---+------+---+---+
    | s | t | r | i | n | g | 1 | '\0' |   |   |
    +---+---+---+---+---+---+---+------+---+---+
    | s | t | r | i | n | g | 2 | '\0' |   |   |
    +---+---+---+---+---+---+---+------+---+---+
    | s | t | r | i | n | g | 3 | '\0' |   |   |
    +---+---+---+---+---+---+---+------+---+---+
    | s | t | r | i | n | g | 4 | '\0' |   |   |
    +---+---+---+---+---+---+---+------+---+---+
    | s | t | r | i | n | g | 5 | '\0' |   |   |
    +---+---+---+---+---+---+---+------+---+---+

    */  

    /* Now, lets work on b */    
    for (i=0 ; i<5; i++) {
        if ((b[i] = malloc(sizeof(char) * COL)) == NULL) {
            printf("unable to allocate memory \n");
            return -1;
        }
    }

    strcpy(b[0], "string1");
    strcpy(b[1], "string2");
    strcpy(b[2], "string3");
    strcpy(b[3], "string4");
    strcpy(b[4], "string5");

    /*

       b[]              0   1   2   3   4   5   6    7     8   9
    +--------+        +---+---+---+---+---+---+---+------+---+---+
    |      --|------->| s | t | r | i | n | g | 1 | '\0' |   |   |
    +--------+        +---+---+---+---+---+---+---+------+---+---+
    |      --|------->| s | t | r | i | n | g | 2 | '\0' |   |   |
    +--------+        +---+---+---+---+---+---+---+------+---+---+
    |      --|------->| s | t | r | i | n | g | 3 | '\0' |   |   |
    +--------+        +---+---+---+---+---+---+---+------+---+---+
    |      --|------->| s | t | r | i | n | g | 4 | '\0' |   |   |
    +--------+        +---+---+---+---+---+---+---+------+---+---+
    |      --|------->| s | t | r | i | n | g | 5 | '\0' |   |   |
    +--------+        +---+---+---+---+---+---+---+------+---+---+

    */

    char (*ptr1)[COL] = a;
    printf("Contents of first array \n");
    for (i=0; i<ROW; i++)
        printf("%s \n", *ptr1++);


    char **ptr2 = b;
    printf("Contents of second array \n");
    for (i=0; i<ROW; i++)
        printf("%s \n", ptr2[i]);

    /* b should be free'd */
    for (i=0 ; i<5; i++)
        free(b[i]);

    return 0;
}
Answer from Sangeeth Saravanaraj on Stack Overflow
🌐
GeeksforGeeks
geeksforgeeks.org β€Ί c language β€Ί array-of-pointers-to-strings-in-c
Array of Pointers to Strings in C - GeeksforGeeks
November 14, 2025 - ... // C Program to Create an Array of Pointers to Strings #include <stdio.h> int main() { // Initialize an array of pointers to strings char* arr[4] = { "C++", "Java", "Python", "JavaScript" }; int n = sizeof(arr) / sizeof(arr[0]); // Print ...
🌐
OverIQ
overiq.com β€Ί c-programming-101 β€Ί array-of-pointers-to-strings-in-c β€Ί index.html
Array of Pointers to Strings in C - C Programming Tutorial - OverIQ.com
But the same thing can be done with an array of pointers to strings. Since each element of games array is a pointer to char or (char*) , it can point to any string literal assigned to it. Let's discuss some operations we can't perform directly in an array of pointers to string. Consider the following example:
Discussions

Pointer to string array in C - Stack Overflow
There are two way of working with array of characters (strings) in C. They are as follows: ... Pictorial representation is available as an inline comment in the code. Based on how you want to represent the array of characters (strings), you can define pointer to that as follows ... They are fundamentally different types (in a subtle way) and so the pointers to them is also slightly different. The following example ... More on stackoverflow.com
🌐 stackoverflow.com
c - array of pointers to strings - Stack Overflow
In your code names is an array of 6 pointers to char. Now each of these pointers can store the starting point (the address of the first character) of a new string. More on stackoverflow.com
🌐 stackoverflow.com
How do I create (and use) an array of pointers to an array of strings in C? - Stack Overflow
I need to create an array of pointers that will each point to an array of strings. The base, is a size 2 array of strings (the length of the strings is unknown at start). For example an array of 2 More on stackoverflow.com
🌐 stackoverflow.com
What are Array of Pointers?
If you have something like const char *argv[] = {"./a.out", "hello", NULL}; You get this in memory: argv β”Œβ”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ ptr β”œβ”€β”€β”€β–Ίβ”‚ ./a.out β”‚ β”œβ”€β”€β”€β”€β”€β”€β”€β”€ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ ptr β”œβ”€β” β”œβ”€β”€β”€β”€β”€β”€β”€β”€ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ NULL β”‚ └─►│ hello β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ You can see that the "./a.out" and "hello" are stored in other places in memory, not inside the array. That’s what a pointer isβ€”a value that can point to another location in memory. Or it can be NULL, which does not point to anything. More on reddit.com
🌐 r/C_Programming
32
37
December 17, 2024
🌐
DEV Community
dev.to β€Ί missmati β€Ί pointers-arrays-strings-in-c-52h3
Pointers , Arrays & Strings in C - DEV Community
October 11, 2022 - Similar to the 2D array we can create the string array using the array of pointers to strings. Basically, this array is an array of character pointers where each pointer points to the string’s first character.
🌐
TutorialsPoint
tutorialspoint.com β€Ί c-program-to-print-array-of-pointers-to-strings-and-their-address
C program to print array of pointers to strings and their address
March 19, 2021 - The C program demonstrating the concept of printing array of pointers to string and the addresses too is given below βˆ’ Β· #include<stdio.h> #include<string.h> void main(){ //Declaring string and pointers, for loop variable// int i; char *a[5]={"One","Two","Three","Four","Five"}; //Printing ...
Top answer
1 of 2
28

There are two way of working with array of characters (strings) in C. They are as follows:

char a[ROW][COL];
char *b[ROW];

Pictorial representation is available as an inline comment in the code.

Based on how you want to represent the array of characters (strings), you can define pointer to that as follows

    char (*ptr1)[COL] = a;
    char **ptr2 = b;

They are fundamentally different types (in a subtle way) and so the pointers to them is also slightly different.

The following example demonstrates the different ways of working with strings in C and I hope it helps you in better understanding of array of characters (strings) in C.

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

#define ROW 5
#define COL 10

int main(void) 
{
    int i, j;
    char a[ROW][COL] = {"string1", "string2", "string3", "string4", "string5"};
    char *b[ROW];

    /*

    a[][]

      0   1   2   3   4   5   6     7    8   9
    +---+---+---+---+---+---+---+------+---+---+
    | s | t | r | i | n | g | 1 | '\0' |   |   |
    +---+---+---+---+---+---+---+------+---+---+
    | s | t | r | i | n | g | 2 | '\0' |   |   |
    +---+---+---+---+---+---+---+------+---+---+
    | s | t | r | i | n | g | 3 | '\0' |   |   |
    +---+---+---+---+---+---+---+------+---+---+
    | s | t | r | i | n | g | 4 | '\0' |   |   |
    +---+---+---+---+---+---+---+------+---+---+
    | s | t | r | i | n | g | 5 | '\0' |   |   |
    +---+---+---+---+---+---+---+------+---+---+

    */  

    /* Now, lets work on b */    
    for (i=0 ; i<5; i++) {
        if ((b[i] = malloc(sizeof(char) * COL)) == NULL) {
            printf("unable to allocate memory \n");
            return -1;
        }
    }

    strcpy(b[0], "string1");
    strcpy(b[1], "string2");
    strcpy(b[2], "string3");
    strcpy(b[3], "string4");
    strcpy(b[4], "string5");

    /*

       b[]              0   1   2   3   4   5   6    7     8   9
    +--------+        +---+---+---+---+---+---+---+------+---+---+
    |      --|------->| s | t | r | i | n | g | 1 | '\0' |   |   |
    +--------+        +---+---+---+---+---+---+---+------+---+---+
    |      --|------->| s | t | r | i | n | g | 2 | '\0' |   |   |
    +--------+        +---+---+---+---+---+---+---+------+---+---+
    |      --|------->| s | t | r | i | n | g | 3 | '\0' |   |   |
    +--------+        +---+---+---+---+---+---+---+------+---+---+
    |      --|------->| s | t | r | i | n | g | 4 | '\0' |   |   |
    +--------+        +---+---+---+---+---+---+---+------+---+---+
    |      --|------->| s | t | r | i | n | g | 5 | '\0' |   |   |
    +--------+        +---+---+---+---+---+---+---+------+---+---+

    */

    char (*ptr1)[COL] = a;
    printf("Contents of first array \n");
    for (i=0; i<ROW; i++)
        printf("%s \n", *ptr1++);


    char **ptr2 = b;
    printf("Contents of second array \n");
    for (i=0; i<ROW; i++)
        printf("%s \n", ptr2[i]);

    /* b should be free'd */
    for (i=0 ; i<5; i++)
        free(b[i]);

    return 0;
}
2 of 2
1

What would be the correct way to solve this problem?

Well, the correct way would be to use a library specifically designed for dealing with multilanguage interfaces - for instance gettext.

Another way, though patchier, would be to use a hash table (also known as "dictionary" or "hash map" or "associative map" in other languages/technologies): Looking for a good hash table implementation in C

It's probably not the answer you were looking for, but you've asked the wrong question to the right problem.

Top answer
1 of 2
11

The issue is that you are not allocating any space for those names. You need to initialize each element in the array if you intend to use it with scanf.

char* names[6];
for( int i = 0; i < 6; ++i )
    names[i] = malloc( 256 * sizeof *names[i] ); // or some other max value

scanf( "%s", names[1] );

Otherwise those pointers will be pointing anywhere in your memory, and attempting to read/write those locations will eventually result in a segmentation fault.

2 of 2
5

In your code names is an array of 6 pointers to char. Now each of these pointers can store the starting point (the address of the first character) of a new string. This means you can store the starting addresses of 6 different strings in your names variable.

But when you use a loop to initialize each of these strings, you need to inform the machine HOW long each string might be, so that it can allocate a continuous block of addresses whose first address can then be stored in your pointer to refer to your string. Thus, you must allocate a certain size you think should be sufficient to store your string (eg: 256 bytes, 1 byte being 1 character). In the absence of this, the machine doesn't know where to store all the bytes of your string and throws a segmentation fault due to illegal memory access.

Thus to do this, each of your 6 pointers must be allocated some space to store a string. This will be done in your loop using malloc(). Based on @K-ballo's code:

char* names[6];
int max_length = 256; // The maximum length you expect
for( int i = 0; i < 6; ++i )
    names[i] = malloc( max_length * sizeof(char) ); // allocates max_length number of bytes

scanf( "%s", names[1] );

So now you basically have a 6 different blocks of max_length continuous char addresses that are each referred to by names[i]. When you do the scanf() it reads the bytes from standard input and puts then into these allocated bytes in memory referred to by names[1].

I had a difficult time at the start understanding all this, so just thought an elaborate explanation would help. :)

Find elsewhere
🌐
Aticleworld
aticleworld.com β€Ί home β€Ί pointer to string array in c, you should know
Pointer to string array in C, you should know - Aticleworld
February 25, 2023 - Basically, this array is an array ... Let us see the syntax for the same, ... You can see the below image in which I have created an array of pointers to a string whose size is 5....
🌐
CodinGeek
codingeek.com β€Ί home β€Ί array of pointers to string - c programming language
Array of pointers to string in C Language | Codingeek
February 24, 2021 - The major drawback that we face while using an array of pointers to string is that we cannot take inputs to the string array using scanf() function. For a normal string array, we can either initialize the array with values or take string inputs from the user.
🌐
RIT
se.rit.edu β€Ί ~swen-250 β€Ί activities β€Ί MicroActivities β€Ί C β€Ί mu_string_ptr_update β€Ί distrib β€Ί index.html
C Strings with Arrays and Pointers
February 27, 2025 - Arrays can be declared with an ... in Hello! + terminating NUL Β· An array name is a constant pointer to the first (0th) array element; thus: mesg == &mesg[0] ; // address of the first character in the message....
🌐
Unstop
unstop.com β€Ί home β€Ί blog β€Ί array of pointers in c explained with detailed code examples
Array Of Pointers In C Explained With Detailed Code Examples
February 29, 2024 - The loop ensures that each string in the array is printed to the console. The loop variable i is incremented in each iteration, allowing us to access each element of the array sequentially. Finally, the main function returns 0, indicating successful program execution. In summary, this code demonstrates the usage of an array of pointers to strings, providing a convenient way to manage and print a collection of strings in a C program.
🌐
Scaler
scaler.com β€Ί home β€Ί topics β€Ί string pointer in c
String Pointer in C - Scaler Topics
January 16, 2024 - In the above example, we have created a character pointer to a string in C that points to the first address of the array str. To print the value stored in the array, we create a while loop until the value at the location pointed by ptr is not null, which indicates that we have not reached the ...
Top answer
1 of 2
3

from cdecl:

declare foo as array of pointer to array 2 of pointer to char

char *(*foo[])[2];

So, foo[0] is a pointer to array 2 of char *

That is the array, but for your use, you want:

declare foo as pointer to array 2 of pointer to char;

char *(*foo)[2];

Now you can do:

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

int main() {
    char *(*foo)[2];

    printf("How many people?\n");
    int n; scanf("%d", &n);

    foo = malloc(sizeof *foo * n);

    for (int i = 0; i < n; i++) {
        char bufFirstName[1024];
        char bufLastName[1024];

        printf("Please insert the #%d first and last name:\n", i+1);

        scanf("%s %s", bufFirstName, bufLastName); 

        char *firstName = malloc(strlen(bufFirstName) + 1);
        char *lastName = malloc(strlen(bufLastName) + 1);

        strcpy(firstName, bufFirstName);
        strcpy(lastName, bufLastName);

        foo[i][0] = firstName;
        foo[i][1] = lastName;
    }

    for (int i = 0; i < n; i++) {
        printf("Name: %s LastName: %s\n", foo[i][0], foo[i][1]);
    }

    return 0;
}

Compile with -std=c99

Note that using scanf, strcpy, strlen like that is unsafe because there can be a buffer overflow.

Also, remember to free your malloc's!

2 of 2
0

Not that your approach is wrong, but have you considered instead using a struct that includes first and last name, and then malloc'ing based on the number of names the user will enter:

typedef struct {
    char* first;
    char* last;
} person;

person* people = malloc(num * sizeof(*person));

This just simplifies pointer interaction. While the way you are doing it is a good exercise in understanding pointers better, it may not be the easiest way to understand.

If you are unable to use structs, you should instead be doing:

char** people;  
people = malloc(2*num*sizeof(char*));  

for (int i = 0; i < 2*num; i++) 
    people[i] = malloc(MAX_NAME_SIZE*sizeof(char));

Now you would need to reference the i th person via:

first name: people[i*2 + 0] 
last name: people[i*2 + 1]
🌐
TutorialsPoint
tutorialspoint.com β€Ί article β€Ί how-to-create-a-pointer-for-strings-using-c-language
How to create a pointer for strings using C language?
March 15, 2026 - char *array_name[size] = {"string1", "string2", "string3", ...}; Here, each element array_name[i] is a pointer to the base address of the corresponding string.
🌐
GeeksforGeeks
geeksforgeeks.org β€Ί c language β€Ί array-of-pointers-in-c
Array of Pointers in C - GeeksforGeeks
July 23, 2025 - As shown in the above example, each element of the array is a pointer pointing to an integer. We can access the value of these integers by first selecting the array element and then dereferencing it to get the value. One of the main applications of the array of pointers is to store multiple strings as an array of pointers to characters.
🌐
Reddit
reddit.com β€Ί r/c_programming β€Ί what are array of pointers?
r/C_Programming on Reddit: What are Array of Pointers?
December 17, 2024 -

So i am learning command lines arguments and just came cross char *argv[]. What does this actually do, I understand that this makes every element in the array a pointer to char, but i can't get around as to how all of this is happening. How does it treat every other element as another string? How come because essentialy as of my understanding rn, a simple char would treat as a single contiguous block of memory, how come turning this pointer to another pointer of char point to individual elements of string?

Top answer
1 of 14
79
If you have something like const char *argv[] = {"./a.out", "hello", NULL}; You get this in memory: argv β”Œβ”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ ptr β”œβ”€β”€β”€β–Ίβ”‚ ./a.out β”‚ β”œβ”€β”€β”€β”€β”€β”€β”€β”€ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ ptr β”œβ”€β” β”œβ”€β”€β”€β”€β”€β”€β”€β”€ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ NULL β”‚ └─►│ hello β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ You can see that the "./a.out" and "hello" are stored in other places in memory, not inside the array. That’s what a pointer isβ€”a value that can point to another location in memory. Or it can be NULL, which does not point to anything.
2 of 14
13
The only thing that’s guaranteeing is contiguous are the double pointers. If you dereference the first element, that is a pointer to a char, and there might be more chars further along if you move down that row with pointer arithmetic. Dereferencing your second element would be a pointer to another char which might make up a string along that row too (if you defined it as such). Those derefenced pointers have no reason to be contiguous in memory. It’s just that the pointers for themselves are. The only contiguity guarantee here from that statement alone is the array of pointers to char *.
🌐
Hero Vired
herovired.com β€Ί learning-hub β€Ί topics β€Ί array-of-pointers-in-c
Array of Pointers in C with Example Program
They initialize the array of pointers with string literals (like β€œNeeraj” or β€œJohn”) These literals are typically stored in a read-only section of memory. The following image describes the memory representation of an Array of Strings. In C language, we can declare arrays of pointers with strings.
Top answer
1 of 4
2

The most "natural" way to define an array of pointers to strings:

char *array[10];

This defines array as an array of 10 pointers to char.

Then

array[i] = string;

to make element i point to the first character of string.

From this assignment, array[i] is basically an alias for string.


Or if you really want a pointer to an array:

char (*array[10])[20];
array[i] = &string;

Note the use of the pointer-to operator & here, to get a pointer to the array itself. Also note that this is very different from the more "natural" way shown above. It all depends on what you actually want to accomplish, what your actual use-case and problem is.


And what happens with your currently shown code is that string decay to a pointer to its first element, so string is the same as &string[0]. Which has the type char *.

You currently define array as an array of pointers to arrays, so each element of array have the type char (*)[20]. That's the type you get with &string.

2 of 4
1

You are defining char (*array[10])[20], it is declaring an array of 10 pointers, and each pointer points to an array of 20 characters (correct).

But in the following line:

array[2] = string;

it will show the warning "assignment from incompatible pointer type", bcz this is not allowed without proper typecast because the types are incompatible in C/C++. In your example, you are trying to assign a array of character string to an element of an array of pointers to arrays of characters. So it will cause warning.

You can change to use this to ignore the warning:

array[2] = &string;

array[2] will hold the address of of the string array, it is point to an array of characters. Therefore, this assignment is compatible.

🌐
Microchip Developer Help
developerhelp.microchip.com β€Ί xwiki β€Ί bin β€Ί view β€Ί software-tools β€Ί compilers β€Ί c-programming β€Ί data-pointers β€Ί arrays-of-pointers
C Programming Arrays Of Pointers - Developer Help
August 26, 2025 - This example shows how you would populate the array of pointers in the following picture. 1 p[0] = "On"; 2 p[1] = "Off"; 3 p[2] = "Main"; 4 p[3] = "Aux"; This would create the strings in memory and initialize each of the pointers in the array to point to a particular string.
🌐
Iditect
iditect.com β€Ί programming β€Ί c β€Ί array-of-strings-in-c.html
An Array of Strings in C
char str[] = "hello"; // or equivalently using pointers char *str_ptr = "hello"; When we talk about an array of strings, we essentially mean an array of character arrays or an array of pointers to strings.