Allocated Array
With an allocated array it's straightforward enough to follow.
Declare your array of pointers. Each element in this array points to a struct Test:
struct Test *array[50];
Then allocate and assign the pointers to the structures however you want. Using a loop would be simple:
array[n] = malloc(sizeof(struct Test));
Then declare a pointer to this array:
// an explicit pointer to an array
struct Test *(*p)[] = &array; // of pointers to structs
This allows you to use (*p)[n]->data; to reference the nth member.
Don't worry if this stuff is confusing. It's probably the most difficult aspect of C.
Dynamic Linear Array
If you just want to allocate a block of structs (effectively an array of structs, not pointers to structs), and have a pointer to the block, you can do it more easily:
struct Test *p = malloc(100 * sizeof(struct Test)); // allocates 100 linear
// structs
You can then point to this pointer:
struct Test **pp = &p
You don't have an array of pointers to structs any more, but it simplifies the whole thing considerably.
Dynamic Array of Dynamically Allocated Structs
The most flexible, but not often needed. It's very similar to the first example, but requires an extra allocation. I've written a complete program to demonstrate this that should compile fine.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
struct Test {
int data;
};
int main(int argc, char **argv)
{
srand(time(NULL));
// allocate 100 pointers, effectively an array
struct Test **t_array = malloc(100 * sizeof(struct Test *));
// allocate 100 structs and have the array point to them
for (int i = 0; i < 100; i++) {
t_array[i] = malloc(sizeof(struct Test));
}
// lets fill each Test.data with a random number!
for (int i = 0; i < 100; i++) {
t_array[i]->data = rand() % 100;
}
// now define a pointer to the array
struct Test ***p = &t_array;
printf("p points to an array of pointers.\n"
"The third element of the array points to a structure,\n"
"and the data member of that structure is: %d\n", (*p)[2]->data);
return 0;
}
Output:
> p points to an array of pointers.
> The third element of the array points to a structure,
> and the data member of that structure is: 49
Or the whole set:
for (int i = 0; i < 100; i++) {
if (i % 10 == 0)
printf("\n");
printf("%3d ", (*p)[i]->data);
}
35 66 40 24 32 27 39 64 65 26
32 30 72 84 85 95 14 25 11 40
30 16 47 21 80 57 25 34 47 19
56 82 38 96 6 22 76 97 87 93
75 19 24 47 55 9 43 69 86 6
61 17 23 8 38 55 65 16 90 12
87 46 46 25 42 4 48 70 53 35
64 29 6 40 76 13 1 71 82 88
78 44 57 53 4 47 8 70 63 98
34 51 44 33 28 39 37 76 9 91
Dynamic Pointer Array of Single-Dynamic Allocated Structs
This last example is rather specific. It is a dynamic array of pointers as we've seen in previous examples, but unlike those, the elements are all allocated in a single allocation. This has its uses, most notable for sorting data in different configurations while leaving the original allocation undisturbed.
We start by allocating a single block of elements as we do in the most basic single-block allocation:
struct Test *arr = malloc(N*sizeof(*arr));
Now we allocate a separate block of pointers:
struct Test **ptrs = malloc(N*sizeof(*ptrs));
We then populate each slot in our pointer list with the address of one of our original array. Since pointer arithmetic allows us to move from element to element address, this is straight-forward:
for (int i=0;i<N;++i)
ptrs[i] = arr+i;
At this point the following both refer to the same element field
arr[1].data = 1;
ptrs[1]->data = 1;
And after review the above, I hope it is clear why.
When we're done with the pointer array and the original block array they are freed as:
free(ptrs);
free(arr);
Note: we do NOT free each item in the ptrs[] array individually. That is not how they were allocated. They were allocated as a single block (pointed to by arr), and that is how they should be freed.
So why would someone want to do this? Several reasons.
First, it radically reduces the number of memory allocation calls. Rather then N+1 (one for the pointer array, N for individual structures) you now have only two: one for the array block, and one for the pointer array. Memory allocations are one of the most expensive operations a program can request, and where possible, it is desirable to minimize them (note: file IO is another, fyi).
Another reason: Multiple representations of the same base array of data. Suppose you wanted to sort the data both ascending and descending, and have both sorted representations available at the same time. You could duplicate the data array, but that would require a lot of copying and eat significant memory usage. Instead, just allocate an extra pointer array and fill it with addresses from the base array, then sort that pointer array. This has especially significant benefits when the data being sorted is large (perhaps kilobytes, or even larger, per item) The original items remain in their original locations in the base array, but now you have a very efficient mechanism in which you can sort them without having to actually move them. You sort the array of pointers to items; the items don't get moved at all.
I realize this is an awful lot to take in, but pointer usage is critical to understanding the many powerful things you can do with the C language, so hit the books and keep refreshing your memory. It will come back.
Answer from teppic on Stack OverflowAllocated Array
With an allocated array it's straightforward enough to follow.
Declare your array of pointers. Each element in this array points to a struct Test:
struct Test *array[50];
Then allocate and assign the pointers to the structures however you want. Using a loop would be simple:
array[n] = malloc(sizeof(struct Test));
Then declare a pointer to this array:
// an explicit pointer to an array
struct Test *(*p)[] = &array; // of pointers to structs
This allows you to use (*p)[n]->data; to reference the nth member.
Don't worry if this stuff is confusing. It's probably the most difficult aspect of C.
Dynamic Linear Array
If you just want to allocate a block of structs (effectively an array of structs, not pointers to structs), and have a pointer to the block, you can do it more easily:
struct Test *p = malloc(100 * sizeof(struct Test)); // allocates 100 linear
// structs
You can then point to this pointer:
struct Test **pp = &p
You don't have an array of pointers to structs any more, but it simplifies the whole thing considerably.
Dynamic Array of Dynamically Allocated Structs
The most flexible, but not often needed. It's very similar to the first example, but requires an extra allocation. I've written a complete program to demonstrate this that should compile fine.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
struct Test {
int data;
};
int main(int argc, char **argv)
{
srand(time(NULL));
// allocate 100 pointers, effectively an array
struct Test **t_array = malloc(100 * sizeof(struct Test *));
// allocate 100 structs and have the array point to them
for (int i = 0; i < 100; i++) {
t_array[i] = malloc(sizeof(struct Test));
}
// lets fill each Test.data with a random number!
for (int i = 0; i < 100; i++) {
t_array[i]->data = rand() % 100;
}
// now define a pointer to the array
struct Test ***p = &t_array;
printf("p points to an array of pointers.\n"
"The third element of the array points to a structure,\n"
"and the data member of that structure is: %d\n", (*p)[2]->data);
return 0;
}
Output:
> p points to an array of pointers.
> The third element of the array points to a structure,
> and the data member of that structure is: 49
Or the whole set:
for (int i = 0; i < 100; i++) {
if (i % 10 == 0)
printf("\n");
printf("%3d ", (*p)[i]->data);
}
35 66 40 24 32 27 39 64 65 26
32 30 72 84 85 95 14 25 11 40
30 16 47 21 80 57 25 34 47 19
56 82 38 96 6 22 76 97 87 93
75 19 24 47 55 9 43 69 86 6
61 17 23 8 38 55 65 16 90 12
87 46 46 25 42 4 48 70 53 35
64 29 6 40 76 13 1 71 82 88
78 44 57 53 4 47 8 70 63 98
34 51 44 33 28 39 37 76 9 91
Dynamic Pointer Array of Single-Dynamic Allocated Structs
This last example is rather specific. It is a dynamic array of pointers as we've seen in previous examples, but unlike those, the elements are all allocated in a single allocation. This has its uses, most notable for sorting data in different configurations while leaving the original allocation undisturbed.
We start by allocating a single block of elements as we do in the most basic single-block allocation:
struct Test *arr = malloc(N*sizeof(*arr));
Now we allocate a separate block of pointers:
struct Test **ptrs = malloc(N*sizeof(*ptrs));
We then populate each slot in our pointer list with the address of one of our original array. Since pointer arithmetic allows us to move from element to element address, this is straight-forward:
for (int i=0;i<N;++i)
ptrs[i] = arr+i;
At this point the following both refer to the same element field
arr[1].data = 1;
ptrs[1]->data = 1;
And after review the above, I hope it is clear why.
When we're done with the pointer array and the original block array they are freed as:
free(ptrs);
free(arr);
Note: we do NOT free each item in the ptrs[] array individually. That is not how they were allocated. They were allocated as a single block (pointed to by arr), and that is how they should be freed.
So why would someone want to do this? Several reasons.
First, it radically reduces the number of memory allocation calls. Rather then N+1 (one for the pointer array, N for individual structures) you now have only two: one for the array block, and one for the pointer array. Memory allocations are one of the most expensive operations a program can request, and where possible, it is desirable to minimize them (note: file IO is another, fyi).
Another reason: Multiple representations of the same base array of data. Suppose you wanted to sort the data both ascending and descending, and have both sorted representations available at the same time. You could duplicate the data array, but that would require a lot of copying and eat significant memory usage. Instead, just allocate an extra pointer array and fill it with addresses from the base array, then sort that pointer array. This has especially significant benefits when the data being sorted is large (perhaps kilobytes, or even larger, per item) The original items remain in their original locations in the base array, but now you have a very efficient mechanism in which you can sort them without having to actually move them. You sort the array of pointers to items; the items don't get moved at all.
I realize this is an awful lot to take in, but pointer usage is critical to understanding the many powerful things you can do with the C language, so hit the books and keep refreshing your memory. It will come back.
It may be better to declare an actual array, as others have suggested, but your question seems to be more about memory management so I'll discuss that.
struct Test **array1;
This is a pointer to the address of a struct Test. (Not a pointer to the struct itself; it's a pointer to a memory location that holds the address of the struct.) The declaration allocates memory for the pointer, but not for the items it points to. Since an array can be accessed via pointers, you can work with *array1 as a pointer to an array whose elements are of type struct Test. But there is not yet an actual array for it to point to.
array1 = malloc(MAX * sizeof(struct Test *));
This allocates memory to hold MAX pointers to items of type struct Test. Again, it does not allocate memory for the structs themselves; only for a list of pointers. But now you can treat array as a pointer to an allocated array of pointers.
In order to use array1, you need to create the actual structs. You can do this by simply declaring each struct with
struct Test testStruct0; // Declare a struct.
struct Test testStruct1;
array1[0] = &testStruct0; // Point to the struct.
array1[1] = &testStruct1;
You can also allocate the structs on the heap:
for (int i=0; i<MAX; ++i) {
array1[i] = malloc(sizeof(struct Test));
}
Once you've allocated memory, you can create a new variable that points to the same list of structs:
struct Test **array2 = array1;
You don't need to allocate any additional memory, because array2 points to the same memory you've allocated to array1.
Sometimes you want to have a pointer to a list of pointers, but unless you're doing something fancy, you may be able to use
struct Test *array1 = malloc(MAX * sizeof(struct Test)); // Pointer to MAX structs
This declares the pointer array1, allocated enough memory for MAX structures, and points array1 to that memory. Now you can access the structs like this:
struct Test testStruct0 = array1[0]; // Copies the 0th struct.
struct Test testStruct0a= *array1; // Copies the 0th struct, as above.
struct Test *ptrStruct0 = array1; // Points to the 0th struct.
struct Test testStruct1 = array1[1]; // Copies the 1st struct.
struct Test testStruct1a= *(array1 + 1); // Copies the 1st struct, as above.
struct Test *ptrStruct1 = array1 + 1; // Points to the 1st struct.
struct Test *ptrStruct1 = &array1[1]; // Points to the 1st struct, as above.
So what's the difference? A few things. Clearly, the first method requires you to allocate memory for the pointers, and then allocate additional space for the structs themselves; the second lets you get away with one malloc() call. What does the extra work buy you?
Since the first method gives you an actual array of pointers to Test structs, each pointer can point to any Test struct, anywhere in memory; they needn't be contiguous. Moreover, you can allocate and free the memory for each actual Test struct as necessary, and you can reassign the pointers. So, for example, you can swap two structures by simply exchanging their pointers:
struct Test *tmp = array1[2]; // Save the pointer to one struct.
array1[2] = array1[5]; // Aim the pointer at a different struct.
array1[5] = tmp; // Aim the other pointer at the original struct.
On the other hand, the second method allocates a single contiguous block of memory for all of the Test structs and partitions it into MAX items. And each element in the array resides at a fixed position; the only way to swap two structures is to copy them.
Pointers are one of the most useful constructs in C, but they can also be among the most difficult to understand. If you plan to continue using C, it'll probably be a worthwhile investment to spend some time playing with pointers, arrays, and a debugger until you're comfortable with them.
Good luck!
c - array of pointers to structures - Stack Overflow
Array of struct pointers
c pointer to array of structs - Stack Overflow
An array of pointers to arrays of structs
Since you want arrays, you need to declare arrays:
char *book[] = { "x", "y", "z",};
int number[] = { 1, 2, 3};
Another issue is
list = (struct data*) malloc( sizeof(struct data) );
//assigning arguments
list[count]->bookname = ...
Here, list is always going to have exactly one element. So if count is anything other than 0, you will be accessing an array out of bounds!
Please change the following piece of code
// declaring array of pointers to structs //
struct data *list;
//not compiling
//struct data *list[3]; ---> There is no problem with this statement.
//creating a new struct
list = (struct data*) malloc( sizeof(struct data) ); ---> //This statement should compilation error due to declaration of struct data *list[3]
to
struct data *list[100]; //Declare a array of pointer to structures
//allocate memory for each element in the array
list[count] = (struct data*) malloc( sizeof(struct data) );
Hi, I am new to C and I want to know why I am getting Segmentation fault error if I declare array of size 10 and try to insert values for first element, but if I make array size to be 1, I am able to print the values correctly.
#include <stdio.h>
typedef struct Person {
char *name;
int age;
} person_t;
int main(void) {
person_t *arr[10];
arr[0]->name = "John Doe";
arr[0]->age = 22;
printf("Name: %s\n", arr[0]->name);
printf("Age: %d\n", arr[0]->age);
return 0;
}The syntax you are looking for is somewhat cumbersome, but it looks like this:
// Declare test_array_ptr as pointer to array of test_t
test_t (*test_array_ptr)[];
You can then use it like so:
test_array_ptr = &array_t1;
(*test_array_ptr)[0] = new_struct;
To make the syntax easier to understand, you can use a typedef:
// Declare test_array as typedef of "array of test_t"
typedef test_t test_array[];
...
// Declare test_array_ptr as pointer to test_array
test_array *test_array_ptr = &array_t1;
(*test_array_ptr)[0] = new_struct;
The cdecl utility is useful for deciphering complex C declarations, especially when arrays and function pointers get involved.
test_t * test_array_ptr is a pointer to test_t. It could be a pointer to single instance of test_t, but it could be a pointer to the first element of an array of instances of test_t:
test_t array1[1024];
test_t *myArray;
myArray= &array1[0];
this makes myArray point to the first element of array1 and pointer arithmetic allows you to treat this pointer as an array as well. Now you could access 2nd element of array1 like this: myArray[1], which is equal to *(myArray + 1).
But from what I understand, what you actually want to do here is to declare a pointer to pointer to test_t that will represent an array of pointers to arrays:
test_t array1[1024];
test_t array2[1024];
test_t array3[1025];
test_t **arrayPtr;
arrayPtr = malloc(3 * sizeof(test_t*)); // array of 3 pointers
arrayPtr[0] = &array1[0];
arrayPtr[1] = &array2[0];
arrayPtr[2] = &array3[0];
So i have struct called Pixel
struct Pixel {
unsigned int r;
unsigned int g;
unsigned int b;
};
and letters defined as arrays of pixels
struct Pixel A [25] = {
{255,255,255},{255,255,255},{0,0,0},{255,255,255},{255,255,255},
{255,255,255},{0,0,0},{255,255,255},{0,0,0},{255,255,255},
{255,255,255},{0,0,0},{255,255,255},{0,0,0},{255,255,255},
{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},
{0,0,0},{255,255,255},{255,255,255},{255,255,255},{0,0,0}
};
now I need an array of pointers to the letters
i understand how to create pointers to array of pixels.
struct Pixel (*Ascii) [25];
but not how to create a array of those pointers
A compound literal has a lifetime of the block it is declared in. So after each iteration of the for loop the literal no longer exists and therefore the pointer to it is invalid, and using such a pointer triggers undefined behavior
Rather than using compound literals, you should allocate memory dynamically for each instance. And since you're initializing the members with all zero values, you can use calloc to return zero-initialized memory.
struct Node* node = calloc(1, sizeof(struct Node));
for (i = 0; i < 10; i++) {
node->children[i] = calloc(1, sizeof(struct Node));
printf("Index: %d, pointer: %p\n", i, node->children[i]);
}
When you use a compound literal, the lifetime of the object is the containing block. When you do this in a loop, the lifetime of each array element ends when the loop iteration completes. So these pointers become invalid.
You need to use dynamic allocation with malloc() to create multiple array elements. You can then copy into the allocated memory by assigning from the compound literal.
There's no need to use a compound literal for the top-level node, you can just use an ordinary local variable there.
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
struct Node {
float value;
bool evaluated;
struct Node* children[10];
};
void main() {
int i;
struct Node node = {
.value = 0,
.evaluated = false,
.children = { 0 }
};
for (i = 0; i < 10; i++) {
node.children[i] = malloc(sizeof *node.children[i]);
*(node->children[i]) = (struct Node) {
.value = 0,
.evaluated = false,
.children = { 0 }
};
printf("Index: %d, pointer: %p\n", i, node->children[i]);
}
}
"Is it true, that structure Array contains array of structures Object?"
No it isn't. Structure Array contains a pointer, not an array. To create an arry you have to allocate memory with malloc or calloc and then assign it to this pointer.
"If I use alloc in function, how can I free it later, if I don't know, how many times I have called that function containing malloc?"
There is free( void* ptr ) to clean the memory you've allocated with malloc or calloc. Have a look here for example - http://www.cplusplus.com/reference/cstdlib/free/
If you want to have an array inside you must have something like this
typedef struct {
unsigned size;
Object items[10];
} Array;
Array contains a pointer to Object, which can be used to point to a dynamically-allocated array, like so:
Array arr;
arr.size = 10;
arr.items = malloc( sizeof *arr.items * arr.size );
Each arr.items[i] has type Object, so you can set the id and name members like so:
arr.items[i].id = 1;
arr.items[i].name = malloc( strlen( "foo" ) + 1 );
if ( arr.items[i].name )
strcpy( arr.items[i].name, "foo" );
When you're done, you'll need to make sure you free each arr.items[i].name before freeing arr.items:
for ( size_t i = 0; i < arr.size; i++ )
{
free( arr.items[i].name ); // assumes memory for arr.items[i].name was
} // allocated with malloc, calloc, or realloc
free( arr.items );
If arr.items[i].name is set to point to a string literal or an auto array, such as
arr.items[i].name = "foo";
...
char some_array[] = "bar";
arr.items[j].name = some_array;
then you would not want to call free on those items.