JavascriptLoser
JavascriptLoser

Reputation: 1962

Why can an array be declared in a struct in this way, and how should it be used?

I have been given some code to build upon and I came across a few strange structures:

typedef struct graph_t* Graph;
typedef struct vertex_t* Vertex;

struct vertex_t {
    int id;
    char *label;

    //Implement a way to store edges...
};


struct graph_t {

    /*# vertices...*/
    int order;

    /*# edges...*/
    int size;

    /*Array of vertices...*/
    Vertex vertices;
};

You can probably see this is a way of storing a graph. However, what I'm confused about is the way the "Array of vertices" has been declared: Vertex vertices. There is nothing to indicate that vertices is actually an array, it simply seems like a single vertex (which wouldn't make sense since a graph can have many vertices).

So how can an array be declared in this way and why does this work?

Also, how would I go about initializing(?) the array and how would it be used? In the same way as a normal array?

EDIT: I forgot to add the typedefs and some missing info, it seems the fact that there is a typedef of vertex_t* is what makes this legal?

Upvotes: 0

Views: 96

Answers (3)

nalzok
nalzok

Reputation: 16097

After the post edited, you still have to malloc() a block of memory to every vertices and label on initialization. For example:

Graph newGraph(size_t n, size_t labelPerVertex)
{
    Graph aGraph = malloc(sizeof (struct graph_t));
    aGraph->vertices = malloc(sizeof (struct vertex_t) * n); // n Vertices
    size_t i;
    for(i = 0; i < n; i++)
        aGraph->vertices[i].label = malloc(labelPerVertex); // array of labelPerVertex chars for every vertex
    return aGraph;
}

Upvotes: 1

Logicrat
Logicrat

Reputation: 4468

There is an extremely bad technique that this might be a prologue to. That would involve first allocating a suitably large chunk of memory, and casting it to struct vertex_t.

For example:

size_t size = sizeof(struct vertex_t) + 1000 * sizeof(Vertex);
struct vertex_t* memory = (struct vertex_t *) malloc(size);
Vertex* array = &memory->vertices;

Now array should be able to take subscripts from [0] to [1000] without getting a memory error. But just because you can do it doesn't mean you should. This is a horrible technique and I can't say enough bad things about it. Don't do it. But it may be where the original author of the code was going.

Upvotes: 1

Magisch
Magisch

Reputation: 7352

/*Array of vertices...*/
Vertex vertices;

The comment is incorrect. It is not an array. It cannot be used as an array of Vertex, because it is not one.

Maybe the implementation notice will be replaced with something that makes Vertex itself into an array of vertices, but that would make the comment still ambigous at best.

Upvotes: 0

Related Questions