Manolete
Manolete

Reputation: 3517

Memory allocation in pointer to pointer to struct

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.

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

Answers (2)

T W Bennet
T W Bennet

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

Deadpool
Deadpool

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

Related Questions