A
Andrew Smallshaw
I'm working on a data structure that began life as a skip list
derivative, but has evolved to the point that it now only has a
passing resemblance to them. Each node of this structure has a
few constant size variables (ints and the like), an array holding
the actual data (chars in this case) and a random number of pointers
to other nodes in the structure.
At the moment my code uses a fixed size array for the contents
(which may or may not be filled) and the call to malloc for each
node is adjusted to allow for the number of the pointers in the
node. Nothing too special there.
However, I am using a _lot_ of these structures and a significant
proportion have comparatively short average lifetimes. With the
expection of a few configuration tables that rarely, if ever, change
once initialised they are my app's only dynamically allocated memory
and I'm slightly concerned about memory fragmentation because they
are of differing lengths. Simply allocating the maximum amount of
memory that could be needed is an unacceptable waste of memory
since the balance is skewed strongly towards low numbers of pointers
- 50% have only a single pointer, 25% two pointers, 12.5% three
and so on up to a maximum of about 25 pointers.
It occurs to me that it is possible to define a fixed sized structure
with a variable number of pointer if the length of the character
length varies in inverse proportion to the number of pointers.
The question is how to do it cleanly. Unions are out of the question
because the number of possible structure types. I considered having
the character buffer start at the same point as the second pointer
and computing the real start of the buffer as needed. However, I
am now leaning towards defining the character array as a maximum
buffer size and having a single pointer array at the end. That
is:
struct structure {
char buffer[MAX_BUFFER_LEN];
struct structure *ptr[1];
};
and using _negative_ array indices to store the extra pointers. I
can easily determine how many pointers are expected algorithmically
- it is something I need to keep track of in any case - and define
a macro to calculate the buffer's real maximum length when it is
needed (not very often). This should work fine but I can't help
feeling it seems a little messy. Does anyone have any better
solutions, or even any views on whether this is worth bothering
about?
derivative, but has evolved to the point that it now only has a
passing resemblance to them. Each node of this structure has a
few constant size variables (ints and the like), an array holding
the actual data (chars in this case) and a random number of pointers
to other nodes in the structure.
At the moment my code uses a fixed size array for the contents
(which may or may not be filled) and the call to malloc for each
node is adjusted to allow for the number of the pointers in the
node. Nothing too special there.
However, I am using a _lot_ of these structures and a significant
proportion have comparatively short average lifetimes. With the
expection of a few configuration tables that rarely, if ever, change
once initialised they are my app's only dynamically allocated memory
and I'm slightly concerned about memory fragmentation because they
are of differing lengths. Simply allocating the maximum amount of
memory that could be needed is an unacceptable waste of memory
since the balance is skewed strongly towards low numbers of pointers
- 50% have only a single pointer, 25% two pointers, 12.5% three
and so on up to a maximum of about 25 pointers.
It occurs to me that it is possible to define a fixed sized structure
with a variable number of pointer if the length of the character
length varies in inverse proportion to the number of pointers.
The question is how to do it cleanly. Unions are out of the question
because the number of possible structure types. I considered having
the character buffer start at the same point as the second pointer
and computing the real start of the buffer as needed. However, I
am now leaning towards defining the character array as a maximum
buffer size and having a single pointer array at the end. That
is:
struct structure {
char buffer[MAX_BUFFER_LEN];
struct structure *ptr[1];
};
and using _negative_ array indices to store the extra pointers. I
can easily determine how many pointers are expected algorithmically
- it is something I need to keep track of in any case - and define
a macro to calculate the buffer's real maximum length when it is
needed (not very often). This should work fine but I can't help
feeling it seems a little messy. Does anyone have any better
solutions, or even any views on whether this is worth bothering
about?