1

I am learning c, and have come across an issue storing and managing structs; let me explain.

I am quite familiar with Java, and I am starting to understand how to properly use pointers and references in c. My goal is to make and store hundreds of stuct:

struct creature{
  int id;
  char name[12];
}

In java, I am able to create an Array like:

creature c [];

and then store and manipulate objects inside that array. I want the same effect in c using a struct "creature".

My first attempt was:

creature *creatures = malloc(sizeof(creature));

I am not entirely sure what that even does. My goal was to create a block of memory that strictly held struct pointers, like the Java array.

from here, I want to create new creature structs, and store their pointers in the creatures variable, that has memory allocated from using malloc.

I hope this was enough information to explain my problem.

Thanks!

kekkles4
  • 111
  • 9

2 Answers2

3

Right, so what you want is an array of pointers. Note that in Java, whenever you have something like:

String s = ...;

This translates to a pointer in c:

String *s = ...;

Let's take the easy case first of a fixed-size array of pointers. This is simply:

creature *creatures[10];
for (var i=0; i < 10; i++) {
    creatures[i] = malloc(sizeof(creature));
}

Now you have an array of pointers to creatures, each malloced separately. But, if you don't know how big your array of creatures should be, then you have to malloc the array of creatures. Note that if you have, say, a malloced int array, you'd do the following:

int *ints = malloc(sizeof(int) * 10);
ints[0]; ints[1]; //etc...

That is, an array is represented as a pointer to the first element. What you want now is an array of pointers, which ends up being a pointer to a pointer:

var numCritters = 10;
creature **creatures = malloc(sizeof(creature *) * numCritters);
for (var i=0; i < numCritters; numCritters++) {
    creatures[i] = malloc(sizeof(creature));
}

The first malloc creates a pointer to an array of creature * pointers. Note we use sizeof(creature *) here, not sizeof(creature), because the array is of pointers, not of creatures.

Each of the next mallocs then creates a pointer to a creature, same as in the case of a fixed-size array.

Be sure to have a free for each malloc - that is, one for each creature * and one for the creature **.

Note that this is different from what Pankrates suggested. Which solution you want to use depends on what you want to do. His creates a big block of creatures:

creature *creatures =  +--------------------+
                       |                    |
                       |                    |
                       |     Creature 0     |
                       |                    |
                       |                    |
                       +--------------------+
                       |                    |
                       |                    |
                       |     Creature 1     |
                       |                    |
                       |                    |
                       +--------------------+
                       |                    |
                       |                    |
                       |     Creature 2     |
                       |                    |
                       |                    |
                       +--------------------+
                       |        ...         |

Whereas mine creates an array of pointers, each one pointing to a creature:

                                             +--------------------+
                                             |                    |
       creature *creatures =  +------+       |                    |
                              | ptr0 | ----> |     Creature 0     |
 +--------------------+       +------+       |                    |
 |                    |   +-- | ptr1 |       |                    |
 |                    |   |   +------+       +--------------------+
 |     Creature 1     | <-+   | ptr2 | --+
 |                    |       +------+   |   +--------------------+
 |                    |       | .... |   |   |                    |
 +--------------------+                  |   |                    |
                                         +-> |     Creature 2     |
                                             |                    |
                                             |                    |
                                             +--------------------+
Community
  • 1
  • 1
Claudiu
  • 224,032
  • 165
  • 485
  • 680
1

You are almost there. malloc takes the number of bytes that you want to allocate as an argument, therefore you need to multiply the size of the struct times the number of structs that you want to allocate:

int number_of_creatures = 10;
creature *creatures = malloc(sizeof(creature) * number_of_creatures);

You should also always check the returned pointer from malloc() to check if the allocation was successful

if (creatures == NULL)
    printf("Allocating memory failed!\n");
Pankrates
  • 3,074
  • 1
  • 22
  • 28