简体   繁体   中英

Creating an array of pointers to structs is malloc needed?

I have created a struct like this

struct PCB
{
   int used;
   char PID[1];
   struct RCB *Other_Resources;
   char type[10];
   struct PCB **list;
   struct PCB *parent;
   struct PCB *children;
   struct PCB *next;
   int priority;
};

then I declared an array of struct PCB * like this

struct PCB *PCBLIST[1024];

my question is do I need to malloc the array of struct pointers in order to use those pointers? I read on another question on here that I should do something like this:

PCBLIST = malloc(1024 * sizeof(struct PCB *));

this is modified slightly, I think in the original question they used MAX instead of giving the actual value like I did 1024.

The error I am getting from gcc c99 is:

error: assignment to expression with array type

but if I try to access an individual struct pointer like with PCBLIST[i]->used I get a seg fault. Can someone shed some light on what I am doing wrong?

You don't need to dynamically allocate the array as that is already allocated by the declaration of the array. You need to allocate struct memory for each of the array entries to point to . Something like:

int ix;
for (ix = 0; ix < sizeof(PCBLIST) / sizeof(PCBLIST[0]); ix++) {
    PCBLIST[ix] = malloc(sizeof(struct PCB));
}

Note that that allocates memory for all the entries of the array. If all the entries are always used then a simpler way would be to use a static allocation by declaring the array as an array of structs rather than an array of pointers to those structs:

struct PCB PCBLIST[1024];

That simplies things by not requiring dynamic allocation. But at the cost of potentially using more memory as it does not allow for a sparsely populated array (not all entries allocated). Which one is best to use depends on how you intend to use the array.

PCBLIST should be a pointer, not an array, because you want to allocate space with malloc, and store the address to a pointer.

and you need to allocate the size of the struct and not the size of the pointer.

struct PCB *PCBLIST;

PCBLIST = malloc(1024 * sizeof(struct PCB));

edit: using malloc is matter of choice and not a must

Here are some examples of doing it with static nodes that are not dynamically allocated.

In the first one I don't change the bits you defined in your question (so you do have an array of pointers to PCB objects - I don't think the is what you were after though because the used flag is not useful if you only create the nodes you use:

#include <string.h> // strcpy

// the PCB structure definition
struct PCB
{
   int used;
   char PID[1];
   struct RCB *Other_Resources;
   char type[10];
   struct PCB **list;
   struct PCB *parent;
   struct PCB *children;
   struct PCB *next;
   int priority;
};

// an uninitialized array of pointers to PCB structures
struct PCB *PCBLIST[1024];

// make some PCB objects
struct PCB pcbParent;
struct PCB pcbChild1;
struct PCB pcbChild2;

int main(void)
{
   // initialize PCBLIST
   for (int i = 0;i < 1024;i++)
      PCBLIST[i] = NULL;

   // initialize parent
   pcbParent.used = 1;
   pcbParent.PID[0] = 0;
   pcbParent.Other_Resources = NULL;
   strcpy(pcbParent.type,"Parent");
   pcbParent.list = PCBLIST;
   pcbParent.parent = NULL; // no parent
   pcbParent.children = &pcbChild1;
   pcbParent.next = NULL; // no next sibling
   pcbParent.priority = 0;
   PCBLIST[0] = &pcbParent;

   // initialize child1
   pcbChild1.used = 1;
   pcbChild1.PID[0] = 1;
   pcbChild1.Other_Resources = NULL;
   strcpy(pcbChild1.type,"Child");
   pcbChild1.list = PCBLIST;
   pcbChild1.parent = &pcbParent;
   pcbChild1.children = NULL; // no children
   pcbChild1.next = &pcbChild2; // next sibling
   pcbChild1.priority = 0;
   PCBLIST[1] = &pcbChild1;

   // initialize child2
   pcbChild2.used = 1;
   pcbChild2.PID[0] = 2;
   pcbChild2.Other_Resources = NULL;
   strcpy(pcbChild2.type,"Child");
   pcbChild2.list = PCBLIST;
   pcbChild2.parent = &pcbParent;
   pcbChild2.children = NULL; // no children
   pcbChild2.next = NULL; // no next sibling
   pcbChild2.priority = 0;
   PCBLIST[2] = &pcbChild2;

   // do some stuff with the nodes

   return 0;
}

It doesn't make much sense to do it that way because you might as well make an array of PCB objects directly - in that case you don't need PCBLIST at all because the list is the array of PCB objects themselves. for example this one makes more sense:

#include <string.h> // strcpy

// the PCB structure definition
struct PCB
{
   int used;
   char PID[1];
   struct RCB *Other_Resources;
   char type[10];
   struct PCB *list;
   struct PCB *parent;
   struct PCB *children;
   struct PCB *next;
   int priority;
};

// an uninitialized array of PCB structures
struct PCB PCBLIST[1024];

int main(void)
{
   // initialize PCBLIST
   for (int i = 0;i < 1024;i++)
   {
      PCBLIST[i].used = 0;
      PCBLIST[i].Other_Resources = NULL;
      PCBLIST[i].list = PCBLIST;
      PCBLIST[i].parent = NULL; // no parent by default
      PCBLIST[i].children = NULL; // no children by default
      PCBLIST[i].next = NULL; // no next sibling by default
   }

   // initialize parent
   PCBLIST[0].used = 1;
   PCBLIST[0].PID[0] = 0;
   strcpy(PCBLIST[0].type,"Parent");
   PCBLIST[0].children = &PCBLIST[1];
   PCBLIST[0].priority = 0;

   // initialize child1
   PCBLIST[1].used = 1;
   PCBLIST[1].PID[0] = 1;
   strcpy(PCBLIST[1].type,"Child");
   PCBLIST[1].parent = &PCBLIST[0];
   PCBLIST[1].next = &PCBLIST[2]; // next sibling
   PCBLIST[1].priority = 0;

   // initialize child2
   PCBLIST[2].used = 1;
   PCBLIST[2].PID[0] = 2;
   strcpy(PCBLIST[2].type,"Child");
   PCBLIST[2].parent = &PCBLIST[0];
   PCBLIST[2].priority = 0;

   // do some stuff with the nodes

   return 0;
}

No, you don't need malloc() . You could initialize the pointers to point to static instances of the structs. If you do use dynamic allocation, you should use calloc() , not malloc() plus arithmetic.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM