DaBurto
DaBurto

Reputation: 43

Array of Structs within the same Struct in C

Is there any way to create a struct, and create an array of that same type struct in C?

e.g.

typedef struct Vertex{
    char letter;
    Vertex edges[];
}Vertex; 

I need an array of structures within that same structure. Is this in any way possible in C?

Upvotes: 1

Views: 7352

Answers (4)

WhozCraig
WhozCraig

Reputation: 66194

Lets assume for a moment that I know what you're really looking for based on your comment to a different answer : a way to reference a bounded number of Vertex structures as edges of a certain vertex, and this must be replicated for all vertex records in your finite set.

Suppose it is a linear list of Vertex structures; an allocated array of a specific size, (or continually extended via a realloc() algorithm):

-----------------------------------------
| Vertex[0] | Vertex[1] | Vertex[2] ... |
-----------------------------------------

Now suppose at the tail of each of the above you need some way of reconciling that

Vertex    Edges
------    -------
[0]       [1],[2]
[1]       [0],[2]
[2]       [0],[1]

Sorry for the use of a simple triangle, but it was the easiest example I could come up with. Anyway moving on. If this is the model you're looking for, you can define your vertex structure as follows:

typedef struct Vertex
{
    char value;     // node 'value'
    int n;          // number of edge indices.
    int *edges;     // dynamic edge index list. [0..(n-1)]
} Vertex;

In defining the above example, you would do the following.

  1. Determine which of the Vertex entries in the global list are edges of the current entry.
  2. Allocate a dynamic index list to hold the slots for those edge 'ids'.
  3. Assign each edge vertex index into your index-list.

A simple (very) example is warranted:

Vertex vtx[3];

// wire vtx[1] and vtx[2] as edges of vtx[0].
vtx[0].value = 'a';
vtx[0].n = 2;
vtx[0].edges = malloc(2 * sizeof(int));
vtx[0].edges[0] = 1;
vtx[0].edges[1] = 2;


// wire vtx[0] and vtx[2] as edges of vtx[1].
vtx[1].value = 'b';
vtx[1].n = 2;
vtx[1].edges = malloc(2 * sizeof(int));
vtx[1].edges[0] = 0;
vtx[1].edges[1] = 2;


// wire vtx[0] and vtx[1] as edges of vtx[2].
vtx[2].value = 'c';
vtx[2].n = 2;
vtx[2].edges = malloc(2 * sizeof(int));
vtx[2].edges[0] = 0;
vtx[2].edges[1] = 1;

So suppose you have vtx[0]. How do you get to his first edge?

Vertex *edge = vtx[ vtx[0].edges[0] ];

From there you can move to that edge's first edge

edge = vtx[ edge->edges[0] ];

Etc. A picture is worth a thousand words:

-------------------------------------
| Vertex[0] | Vertex[1] | Vertex[2] |
| value = a | value = b | value = c |
| count = 2 | count = 2 | count = 2 |
|-----------|-----------|-----------|
|edges[0]=1 |edges[0]=0 |edges[0]=0 |
|edges[1]=2 |edges[1]=2 |edges[1]=1 |
-------------------------------------

Cleanup requires you free() the index list pointer in each Vertex of the global list. If the global list itself is dynamically allocated, you free() it too. In our sample above it is not.

I hope that at least gives you an idea of how you can do this without having to go malloc-nutz and copy data all over the place. In summary, in this example the Vertex node list can be exploited to maintain the information you really want (edges) without having to make copies of Vertex nodes whatsoever.

Upvotes: 1

Fity
Fity

Reputation: 31

Just do as Jonathan Wood and ouah said. In C, we cannot put a array(in fact, the struct itself) into the struct. However, a pointer to the struct will work really fine. For example, when we realize a list by C, we often use the following struct:

struct listname{
    void *value;
    struct listname *next;
}

Then, in order to put a array, put a pointer which points to a array of the struct into it.

Upvotes: 1

Jonathan Wood
Jonathan Wood

Reputation: 67175

You could do something like this:

typedef struct _Vertex {
    char letter;
    struct _Vertex* pEdges;
} Vertex; 

Vertix v;
v.pEdges = (Vertex*)malloc(sizeof(Vertex) * n);
v.pEdges[0].letter = '0';

You'd need some way to know/track how many items were in each array.

Upvotes: 3

ouah
ouah

Reputation: 145829

typedef struct Vertex{
   char letter;
   struct Vertex *edges;
   int n;
}Vertex; 

or

typedef struct Vertex Vertex;
struct Vertex{
   char letter;
   Vertex *edges;
   int n;
};

For example:

Vertex bla;
const int n = 42;
bla.n = n;
bla.edges = malloc(n * sizeof (*bla.edges));  

Upvotes: 0

Related Questions