tags:

views:

2048

answers:

3

Hello,

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,

+7  A: 

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.

Ryan Graham
+2  A: 

ports is and array of pointers to port_t objects, so by doing ports[0] you get a pointer, not an object, and you need to access it with ->

Grab a good resource on pointers in C and read it from cover to cover. There are also tutorials on reading C declarations. You won't be able to understand this topic by getting answers to random questions.

Here's a link worth reading.

kyku
+5  A: 
*ports[MAX_PORTS]. Am I creating 10 pointers that point to port objects?

Yes, you're making an array of ten pointers

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

...but this line is nonsense. It's the same as this:

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

ie. You're setting the first pointer to point to enough memory for two ports.

For such a small thing it would make much more sense to make ten ports but not use them all:

#define MAX_PORTS 10

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

/* number of ports in use */
int numPorts = 0;

int main(void)
{
    numPorts = 3;
    for (int i=0; i<numPorts; i++) {
     ports[i].port_id = i;
     printf("port_id %d: %d\n", i, ports[i].port_id);
    }
    return 0;
}
Jimmy J
Cannot upvote enough. Using dynamic allocation for something as piddly as 10 port_t's needlessly overcomplicates code.
jdizzle