"Nesting" {...} like that is used to initialize nested objects. For instance, in: int a[][4] = { { 1, 2, 3, 4 }, { 5, 6, 7, 8 } }; the nested objects are 4-element arrays of int. Both of these nested objects have to be the same kind of object, of course, because the a array must have the same type for all of its elements. To initialize an array of pointers, you actually need a series of things that have addresses. A string like "January" is an array allocated somewhere in memory, so it has an address. But {...} is not an array. It is just the special syntax you can use to initialize an array. But what you can use instead are what are called "compound literals". For instance: int *v[] = { (int []){ 1, 3, 5, 7, 9 }, (int []){ 2, 4, 6, 8 } }; tells the compiler to put a 5-element array and a 4-element array somewhere in memory. These arrays each undergo ordinary array-to-pointer decay, so you end up with two pointer values. And so the array v is initialized with these two pointer values. Take note I've skipped over some hairy details regarding how {...} actually works here. There are certain rules followed by your compiler if your nested initializers don't have the correct number of elements. Also, due to some historical baggage in the C language, the braces for nested initializers can be omitted in certain cases, and "unnecessary" braces can sometimes be left in. This is actually the reason why you got that warning; the compiler is treating your statement as if you had written: int *v[] = { 1, 2 }; Of course, this is still just as wrong your code. Answer from aioeu on reddit.com
🌐
Reddit
reddit.com › r/c_programming › how to initialize pointer arrays?
r/C_Programming on Reddit: How to initialize pointer arrays?
September 4, 2023 -

I’m dreading K&R chapter five about pointers and arrays right now. The book initialized an array of char pointers like this :

char *name[] = { “January“, “aFebruary”};

So I thought I can do something like :

int *v[] = { {1, 3, 5, 7, 9}, {2, 4, 6, 8}};

But the compiler gives a warning in the lines of

initialization of ‘int *’ from ‘int’ makes pointer from integer without a cast

Top answer
1 of 3
13
"Nesting" {...} like that is used to initialize nested objects. For instance, in: int a[][4] = { { 1, 2, 3, 4 }, { 5, 6, 7, 8 } }; the nested objects are 4-element arrays of int. Both of these nested objects have to be the same kind of object, of course, because the a array must have the same type for all of its elements. To initialize an array of pointers, you actually need a series of things that have addresses. A string like "January" is an array allocated somewhere in memory, so it has an address. But {...} is not an array. It is just the special syntax you can use to initialize an array. But what you can use instead are what are called "compound literals". For instance: int *v[] = { (int []){ 1, 3, 5, 7, 9 }, (int []){ 2, 4, 6, 8 } }; tells the compiler to put a 5-element array and a 4-element array somewhere in memory. These arrays each undergo ordinary array-to-pointer decay, so you end up with two pointer values. And so the array v is initialized with these two pointer values. Take note I've skipped over some hairy details regarding how {...} actually works here. There are certain rules followed by your compiler if your nested initializers don't have the correct number of elements. Also, due to some historical baggage in the C language, the braces for nested initializers can be omitted in certain cases, and "unnecessary" braces can sometimes be left in. This is actually the reason why you got that warning; the compiler is treating your statement as if you had written: int *v[] = { 1, 2 }; Of course, this is still just as wrong your code.
2 of 3
4
The issue is that int* v[] expects each element to be a pointer to an int. This can be achieved by declaring auxiliary arrays and using their addresses as initializers: int arr1[] = {1, 3, 5, 7, 9}; int arr2[] = {2, 4, 6, 8}; int *v[] = { arr1, arr2 }; Since C99 one can use "compound literals" to create unnamed object that can be used only once. int *v[] = { (int[]){1, 3, 5, 7, 9}, (int[]){2, 4, 6, 8}};
🌐
TutorialsPoint
tutorialspoint.com › cprogramming › c_initialization_of_pointer_arrays.htm
Initialization of Pointer Arrays in C
A pointer variable can be initialized at the time of declaration, by assigning it the address of an existing variable. The following snippet shows how you can initialize a pointer − ... By default, all the variables including the pointer variables belong to the "auto ...
🌐
GeeksforGeeks
geeksforgeeks.org › c language › how-to-initialize-array-of-pointers-in-c
How to Initialize Array of Pointers in C? - GeeksforGeeks
July 23, 2025 - // C program to initialize array ... int main() { // declare an array of pointers to store address of // elements in array int* ptr[4]; // initializing the pointers to the NULL for (int i = 0; i < 4; i++) { ptr[i] = NULL; } // Print the ...
🌐
IncludeHelp
includehelp.com › c › pointer-to-an-array-of-integers-declarations-initialization-with-example.aspx
Pointer to an array of integers in C language [Declarations, Initialization with Example]
3) Now, Initialize the pointer with the base address of an array of integers A) By using array name (it returns the base address of an array) ptr = arr; B) By using address of first element of integers array (it also returns the base address of an array) ptr = &arr[0]; 4) Now, pointer contains ...
🌐
TutorialsPoint
tutorialspoint.com › cprogramming › c_array_of_pointers.htm
Array of Pointers in C
If we store the address of an array in another pointer, then it is possible to manipulate the array using pointer arithmetic. To create an array of pointers in C language, you need to declare an array of pointers in the same way as a pointer declaration.
🌐
GeeksforGeeks
geeksforgeeks.org › c language › how-to-declare-and-initialize-an-array-of-pointers-to-a-structure-in-c
How to Declare and Initialize an Array of Pointers to a Structure in C? - GeeksforGeeks
July 23, 2025 - So this is how we declare and initialize a 2D array of structure pointers. Here, we use the same structure - "node" and made 4 pointers for it which were - "structure_ptr1", "structure_ptr2", "structure_ptr3" and "structure_ptr4". After that, we declared a 2D array of size - 2 X 2 namely - structure_array. Note: The data type of the array must be the same as that of the structure followed by * (asterisk) sign, which signifies array of structure pointers. As we know that in C language, we can also dynamically allocate memory for our variables or arrays.
Top answer
1 of 4
23

Suppose you have an array of int of length 5 e.g.

int x[5];

Then you can do a = &x;

 int x[5] = {1};
 int (*a)[5] = &x;

To access elements of array you: (*a)[i] (== (*(&x))[i]== (*&x)[i] == x[i]) parenthesis needed because precedence of [] operator is higher then *. (one common mistake can be doing *a[i] to access elements of array).

Understand what you asked in question is an compilation time error:

int (*a)[3] = {11, 2, 3, 5, 6}; 

It is not correct and a type mismatch too, because {11,2,3,5,6} can be assigned to int a[5]; and you are assigning to int (*a)[3].

Additionally,

You can do something like for one dimensional:

int *why = (int p[2]) {1,2};

Similarly, for two dimensional try this(thanks @caf):

int (*a)[5] = (int p[][5]){ { 1, 2, 3, 4, 5 } , { 6, 7, 8, 9, 10 } };
2 of 4
5

{11,2,3,5,6} is an initializer list, it is not an array, so you can't point at it. An array pointer needs to point at an array, that has a valid memory location. If the array is a named variable or just a chunk of allocated memory doesn't matter.

It all boils down to the type of array you need. There are various ways to declare arrays in C, depending on purpose:

// plain array, fixed size, can be allocated in any scope
int array[5] = {11,2,3,5,6};
int (*a)[5] = &array;

// compound literal, fixed size, can be allocated in any scope
int (*b)[5] = &(int[5]){11,2,3,5,6};

// dynamically allocated array, variable size possible
int (*c)[n] = malloc( sizeof(int[n]) );

// variable-length array, variable size
int n = 5;
int vla[n];
memcpy( vla, something, sizeof(int[n]) ); // always initialized in run-time
int (*d)[n] = &vla;
Find elsewhere
Top answer
1 of 4
20

The malloc calls in the first few examples allocate a block of memory and assign a pointer to that memory to arr. As soon as you assign to arr again, the pointer value is overwritten, and you've lost track of that allocated memory -- i.e., you've leaked it. That's a bug right there.

In other words, if you allocate a block of memory using using malloc(), then you can write data into it using array syntax (for example):

int* arr = (int *) malloc(sizeof(int) * 5);
for (int i=0; i<5; ++i)
    arr[i] = i;

But you can't assign anything else directly to arr, or you lose the pointer to that block of memory. And when you allocate a block using malloc(), don't forget to delete it using free() when you don't need it anymore.

An array is not a pointer-to-integer; it's an array. An array name is said to "decay to a pointer" when you pass it as an argument to a function accepting a pointer as an argument, but they're not the same thing.

Regarding your last question: that's actually the difference between an array and a pointer-to-type: the compiler knows the size of an array, but it does not know the size of a block pointed to by an arbitrary pointer-to-type. The answer, unfortunately, is no.

But since you're writing C++, not C, you shouldn't use arrays anyway: use `std::vector'! They know their own length, plus they're expandable.

2 of 4
7

When you say: ptr = {1,2,3,4,5}, you make ptr point to a memory in the data segment, where constant array {1,2,3,4,5} resides and thus you are leaking memory. If you want to initialize your memory, just after allocation, write: ptr[0]=1; ptr[1]=2; and so on. If you want to copy data, use memcpy.

Top answer
1 of 6
14
int * array[10];

defines 10 pointers on 10 int arrays statically

To go dynamic:

int **array = new int *[10];

Better solution since you use C++: use std::vector

std::vector<int *> v;
v.resize(10);
v[2] = new int[50];  // allocate one array

Since we're using vectors for the array of pointers, lets get rid of the pointers completelely

std::vector<std::vector<int> > v;
v.resize(10);
v[2].resize(50);  // allocate one array

Then access the array like a matrix:

v[3][40] = 14;

Going further, one way to initialize all the rows, using C++11, making a 10x50 int matrix in the end (but size can also change within the loop if we want). Needs gcc 4.9 and g++ -std=c++11 to build

std::vector<std::vector<int> > v;
v.resize(10);
for (auto &it : v)
{
   it.resize(50);  // allocate arrays of 50 ints
}
2 of 6
6

In general in most cases there is no great sense to initialize the array with exact addresses. You could assign the addresses or allocate appropriate memory during the usage of the array.

Usually there is sense to initialize an array of pointers with null pointers. For example

int * array[10] = {};

If you want to declare the array and at once to allocate memory for each element of the array you could write for example

int * array[10] = 
{ 
    new int, new int, new int, new int, new int, new int, new int, new int, new int, new int 
}; 

or

int * array[10] = 
{ 
    new int( 0 ), new int( 1 ), new int( 2 ), new int( 3 ), new int( 4 ), new int( 5 ), new int( 6 ), new int( 7 ), new int( 8 ), new int( 9 ) 
}; 

But in any case it would be better to do the assignment using some loop or standard algorithm because in general the array can have more than 10 elements.

Also you should not forget to delete all allocated memory. For example

std::for_each( std::begin( array ), std::end(array ), std::default_delete<int>() );

Or if you have already defined objects of type int you could write for example

int x0, x1, x2, x3, x4, x5, x6, x7, x8, x9;
//...
int * array[10] = 
{ 
    &x0, &x1, &x2, &x3, &x4, &x5, &x6, &x7, &x8, &x9 
}; 

Such an initialization is used very often for arrays of function pointers.

🌐
Microchip
skills.microchip.com › fundamentals-of-the-c-programming-language-part-iii › 700308
Arrays of Pointers
The elements of p[], such as p[1], are pointers to char. Initializing an element of an array of pointers is just like initializing ordinary pointers, but we must include the array index.
🌐
Linux Hint
linuxhint.com › create-use-array-pointers-c
Create and Use Array of Pointers in C – Linux Hint
Here, the dataType refers to the type of array, which can be an integer, float, a character, or a pointer. The arrName refers to the name given to the array, which can be any descriptive term for the variable as long it obeys the rules of naming a variable in C. Finally, the arrSize refers to the total number of items to store in the array. This value is constant and unchangeable once declared. For example, we can define an array of integers to store 10 values as: ... We can also define and initialize an array in the same line.
🌐
Microchip Developer Help
developerhelp.microchip.com › xwiki › bin › view › software-tools › c-programming › data-pointers › pointers-arrays
C Programming Pointers and Arrays - Developer Help
The first method is to simply assign the array variable to the pointer variable. By definition, an array variable without the square brackets and index represents the address of the array, which is also the address of the first element. So, we can simply say p = x; without the & (address of) ...
🌐
Cprogramming
cboard.cprogramming.com › c-programming › 175326-initializing-pointer-array-pointers-compound-literals.html
Initializing a pointer to an array of pointers with compound literals
list could also be defined as a pointer to a fixed size array of pointers but that would require the structure to be defined with a list member that is large enough to hold the largest list. Which isn't ideal when there are lots of small lists and a single large list. ... After some further testing it seems that the errror C2099: initializer is not constant only occurs when list is initialized within a scope/block of code.
Top answer
1 of 4
9

You need to allocate enough memory for 16 pointers, not just one.

arr = (char **)calloc(16, sizeof(char*));

What happens with your code is that arr has enough memory only for one pointer, so arr[0] = <something> is correct, but arr[1] and higher is touching memory that doesn't belong to the program.

Additionally, the way you assign the string pointers is wrong. You are assigning 0 or 1 values, depending on whether the result if calloc is NULL. You need to add parentheses there:

if ((arr[i] = (char *)calloc(1, 2*sizeof(char))) == NULL)
    perror("Memory cannot be allocated to arr[%d]", i);

Er even better:

for(i = 0; i < 16; i++) {
    arr[i] = (char *)calloc(1, 2*sizeof(char));
    if (arr[i] == NULL) {
        perror("Memory cannot be allocated to arr[%d]", i);
    }
}
2 of 4
6

When you use calloc, it is customary to use the first parameter to pass the number of elements in the array and the second parameter to pass the size of an element. So, to allocate an array of 16 pointers, one'd normally use calloc(16, <pointer size>), not calloc(1, 16 * <pointer size>), although both do the same thing. In your code you apparently completely forgot about 16 and allocated only 1 pointer.

Don't cast the result of 'calloc'.

Avoid using sizeof(<type>) when calculating size for memory allocation functions. Prefer to use sizeof *<pointer> instead.

If you want to store srings of length 2, you need a buffer of at least 3 characters long (an extra character for zero-terminator).

Memory allocation failure doesn't normally set errno, so perror is not an appropriate function to use here.

Yor assignment to arr[i] in if condition is missing braces. The operations are associated incorrectly. It won't compile as is.

char **arr; 
arr = calloc(16, sizeof *arr); 
for(i = 0; i < 16; i++)
    if((arr[i] = calloc(3, sizeof *arr[i]) == NULL)
        fprintf(stderr, "Memory cannot be allocated");

Finally, an unnamed "magic constant" (16 and 3) is most of the time not a good idea.

🌐
OverIQ
overiq.com › c-programming-101 › array-of-pointers-in-c
Array of Pointers in C - C Programming Tutorial - OverIQ.com
Just like we can declare an array of int, float or char etc, we can also declare an array of pointers, here is the syntax to do the same. Syntax: d…
🌐
StudySmarter
studysmarter.co.uk › computer science › computer programming › pointer array c
Pointer Array C: Function, Structures, 2D, String | StudySmarter
Declare a structure data type, create an array of pointers to the structure data type, allocate memory for each element and initialise them, and use the array index and arrow operator or dereference and dot operator to access structure members.
🌐
IBM
ibm.com › docs › en › zos › 2.4.0
Initialization of pointers
We cannot provide a description for this page right now
🌐
Scaler
scaler.com › topics › c › array-of-pointers-in-c
Array of Pointers in C - Scaler Topics
March 21, 2022 - When you initialize the array of pointers with string literals (like "John" or "Jane"), these literals are typically stored in a read-only section of the memory. Illustration: Imagine the memory as a series of boxes, where each box represents a memory location, and its size denotes the number of bytes it can hold.