Reputation: 3517
I am doing this to understand the memory allocation requirement in C. Let's see this little example:
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
typedef struct {
float x[2];
float y[2];
} particle_t;
int main()
{
srand((unsigned int)time(NULL));
int i;
particle_t* list = (particle_t*) malloc(10*(sizeof(particle_t)) );
particle_t** pp = (particle_t**) malloc(10*(sizeof(particle_t*)) );
//for(int i=0;i< 10;i++)
// pp[i] = (particle_t*) malloc((sizeof(particle_t)) );
//populate
for ( i=0; i<10; i++){
list[i].x[0]= ((float)rand())/RAND_MAX;
list[i].x[1]= ((float)rand())/RAND_MAX;
list[i].y[0]= ((float)rand())/RAND_MAX;
list[i].y[1]= ((float)rand())/RAND_MAX;
pp[i] = &list[i];
}
//Read
for(int i=0;i<10;i++)printf("list[%d].X(0) = %f\n",i, list[i].x[0]);
for(int i=0;i<10;i++)printf("pp[%d].X(0) = %f\n",i, pp[i]->x[0]);
printf("********************************\n");
//Write
for(int i=0;i<10;i++){
pp[i]->x[0] = 5.9 * ((float)rand())/RAND_MAX;
pp[i]->x[1] = 5.9 * ((float)rand())/RAND_MAX;
pp[i]->y[0] = 5.9 * ((float)rand())/RAND_MAX;
pp[i]->y[1] = 5.9 * ((float)rand())/RAND_MAX;
}
for(int i=0;i<10;i++)printf("list[%d].X(0) = %f\n",i, list[i].x[0]);
for(int i=0;i<10;i++)printf("pp[%d].X(0) = %f\n",i, pp[i]->x[0]);
return 0;
}
Here I have created a list of particle_t
structs. Supposedly one of the advantages of working with pointers is that you don't need to replicate the data. So, let's think that I want to create a number of small lists out of that main list.
Option 1
memcpy
every single element in list
to the different small lists.
Option 2
create a list of pointers that point to list
.
Going with Option 2, I created a pointer to pointer to a particle_t
struct. Then allocate memory for as many pointers I need (10 in the example). Now is when I am not sure how to proceed. I would have thought that I need to allocate memory for each pointer to point to a particle_t
struct. However as we can see in the example that is not required, at least not always. It might depend on the compiler though.
The question is, should I always allocate memory to accommodate a pointer to a struct even though it might no be required?
Upvotes: 0
Views: 97
Reputation: 383
What you have created in your example is an array of particle, and another array of pointers to particle. Your first loop fills data into both arrays so that the pointer located in pp[i]
points to the particle in list[i]
.
If your question means "should I always allocate memory to accommodate a pointer to a struct" means "should I always run malloc to make space for every struct pointer I create," the answer is "no," as your code demonstrates. A non-NULL pointer should point to some valid memory space. Very often, you allocate new space immediately by calling malloc. But you can also make the pointer point to space that already exists and is in use. In your case, space from your first array, which is now effectively shared.
Make sure when you run free, you send it exactly the values you got from malloc, exactly one free for each malloc.
In either case, be careful and draw yourself a picture of it so you know what's going on.
Upvotes: 1
Reputation: 94
A pointer needs 4 bytes (32 bit machine) or 8 bytes (64 bit machine). If you are creating a list of pointers, you should definitely allocate memory to that list and then store those pointers. The short answer you should always allocate memory to accommodate any type of pointer (whether it is normal or it points to a struct) because structure does not claim any memory for itself .
Upvotes: 0