struct c dynamically allocate memory

ant2009 picture ant2009 · Mar 6, 2009 · Viewed 12.2k times · Source

I am using a struct and I want to initialize a maximum of 10 ports. However, when the program is running it could be a lot less, we don't know until run-time. However, this will be the max. I have never done struct like this before, as I normally dynamically allocate using calloc and delcare like this *ports as the value type.

However, I can't understand this

*ports[MAX_PORTS]. Am I creating 10 pointers that point to port objects?

And

*ports = (struct port_t*) calloc(2, sizeof(*ports)); 

Looks like I am allocating a single pointer that points to 2 port objects allocated on the free store?

I can't understand why I am using a dot operator with a arrow operator? ports[0]->port_id = 20; printf("port_id: %d\n", ports[0]->port_id);

#include <stdio.h>
#include <stdlib.h>

#define MAX_PORTS 10

struct port_t
{
    int port_id;
    char name;
} *ports[MAX_PORTS];

int main(void)
{
    *ports = (struct port_t*) calloc(2, sizeof(*ports));

    ports[0]->port_id = 20;

    printf("port_id: %d\n", ports[0]->port_id);

    return 0;
}

normally, what I have done in the passed is this:

struct port_t
{
    int port_id;
    char name;
} *ports;

ports = (struct port_t*) calloc(2, sizeof(*ports));

And then assign with either of the following below. However, the previous programmer has declared everything like I have displayed at the top so I can't change anything.

ports[0].port_id = 10;
ports->port_id = 10;

Many thanks for any suggestions,

Answer

Ryan Graham picture Ryan Graham · Mar 6, 2009

Your first code block has

struct port_t
{
    int port_id;
    char name;
} *ports[MAX_PORTS];

which is an array of pointers. This means later when you use

ports[0]->port_id

you are dereferencing the first pointer in the array. There is also some ugliness surrounding the size of what you are actually calloc'ing. You're actually replacing your array of 10 with an array of 2. What you've got there is generally ugly and error prone.

I believe your intentions are more along the lines of:

struct port_t
{
    int port_id;
    char name;
} *ports;

int main(void)
{
    *ports = (struct port_t*) calloc(2, sizeof(*ports));

    ports[0].port_id = 20;

    printf("port_id: %d\n", ports[0].port_id);

    return 0;
}

Since you are using C99, you could avoid calloc()/malloc(), if you really want to by using C99's variable array declaration.

port_t array_on_mains_stack[some_runtime_port_count];
ports = array_on_mains_stack;

The trick there is that since it is on the stack, it is only valid from that function and any function called by it. Once you return from that function, it is of course freed.