0

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?

3
  • @user3121023 I am not allocating memory for pp[i] (it's commented out in the example), I am just pointing to a different memory location &list[i] Commented Jul 20, 2018 at 10:15
  • @Manolete Do you want all 10 lists in pp to point to the same list? If yes, i think what you did would make pp[0] store address of list[0], pp[1] store address of list[1]. And remember list[0], list[1] have just a single particle_t Commented Jul 20, 2018 at 10:18
  • start your debugger. You can easly figure everything yourself Commented Jul 23, 2018 at 2:20

2 Answers 2

1

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.

Sign up to request clarification or add additional context in comments.

Comments

0

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 .

3 Comments

@_Deadpool So the for(int i=0;i< 10;i++)pp[i] = (particle_t*)malloc((sizeof(particle_t)) ); section that is commented out should be uncommented out.
particle_t** pp = (particle_t**) malloc(10*(sizeof(particle_t*)) ); In this line you already gave memory of 8*10 bytes for pp . Now you donot need to allocate any extra memory.
The number of bytes for a pointer can always be from 1 to n. It depends on the number of bits in a byte/char and the number of bytes per pointer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.