I saw some people use this structure for Trie nodes:
struct trie_node_st {
int count;
struct trie_node_st *next[TREE_WIDTH];
};
Is is low efficiency, since we don't always need TREE_WIDTH as length for each array.
Or am I misunderstanding something?
It's a CPU/memory trade off. By allocating it up front you use a certain minimum amount of memory to store those pointers (TREE_WIDTH * sizeof (struct trie_node_st *)) bytes, you use less CPU later because this is done at compile time (unless you allocate the struct with malloc()). However, this is hardly an overhead. Even if you had a ton of pointers, it wouldn't matter. The likely design decision was just that the programmer did not feel like having to dynamically allocate an array of pointers to struct trie_node_st each time he used this structure.
Related
So I'm looking at a solution to some coding interview type questions, and there's an array inside a struct
#define MAX_SIZE 1000000
typedef struct _heap {
int data[MAX_SIZE];
int heap_size;
}heap;
heap* init(heap* h) {
h = (heap*)malloc(sizeof(heap));
h->heap_size = 0;
return h;
}
This heap struct is later created like so
heap* max_heap = NULL;
max_heap = init(max_heap);
First of all, I'd wish this was written in C++ style than C, but secondly if I'm just conscerned about the array, I'm assuming it is equivalent to solely analyze the array portion by changing the code like this
int* data = NULL;
data = (int*)malloc(1000000 * sizeof(int));
Now in that case, is there any problems with declaring the array with the max size if you are probably just using a little bit of it?
I guess this boils down to the question of when an array is created in the heap, how does the system block out that portion of the memory? In which case does the system prevent you from accessing memory that is part of the array? I wouldn't want a giant array holding up space if I'm not using much of it.
is there any problems with declaring the array with the max size if you are probably just using a little bit of it?
Yes. The larger the allocation size the greater the risk of an out-of-memory error. If not here, elsewhere in code.
Yet some memory allocation systems handle this well as real memory allocations do not immediately occur, but later when needed.
I guess this boils down to the question of when an array is created in the heap, how does the system block out that portion of the memory?
That is an implementation defined issue not defined by C. It might happen immediately or deferred.
For maximum portability, code would take a more conservative approach and allocate large memory chunks only as needed, rather than rely on physical allocation occurring in a delayed fashion.
Alternative
In C, consider a struct with a flexible member array.
typedef struct _heap {
size_t heap_size;
int data[];
} heap;
If you want to allocate an array of struct you can do it statically by declaring something like
struct myStruct myStructArray[100];
or dinamically with something like
struct myStruct *myStructArray = calloc(100, sizeof(struct myStruct) );
but in this case you are responsible for freeing the memory.
In many applications and samples I found a mixed approach:
struct wrapperStruct
{
int myInt;
struct myStruct myStructArray[1];
};
Then the allocation is performed like this
int n = 100;
size_t memory_size = sizeof(struct wrapperStruct) + (n - 1) * sizeof(struct myStruct);
struct wrapperStruct *wrapperStruct_p = calloc(1, memory_size);
So (if I understood correctly) since the array is the last member of the struct and the field of a struct respect the same position in memory then you are "extending" the single entry array myStructArray with 99 entries.
This allow you to safety write something like wrapperStruct_p.myStructArray[44] without causing a buffer overflow and without having to create a dynamic allocated array of struct and then take care of the memory disposal at the end. So the alternative approach would be:
struct wrapperStruct
{
int myInt;
struct myStruct *myStructArray;
};
struct wrapperStruct *wrapperStruct_p = calloc(1, sizeof(struct wrapperStruct) );
wrapperStruct_p.myStructArray = calloc(100, sizeof(struct myStruct) )
The question is what happens when you try to free the wrapperStruct_p variable ?
Are you causing a memory leak ?
Is the C memory management able to understand that the array of struct is made of 100 entries and not 1 ?
What are the benefits of the first approach apart from not having to free the pointer inside the struct ?
The question is what happens when you try to free the wrapperStruct_p
variable ?
Are you causing a memory leak ?
Most likely, but not necessary. The memory for the inner dynamic array is not freed, but you could still free it later if you saved the pointer address to some other variable.
Is the C memory management able to understand that the array of struct is made of 100 entries and not 1 ?
"C memory management" takes care of stack and heap allocations (the latter using systemcalls so maybe it's not really a "C memory management"), it doesn't do much else other than provide syntactic sugar on top of assembler (unlike garbage collected languages like Java or other).
C itself doesn't care about how many entries are somewhere and what part of memory you access (SEGFAULTS are the OS response to memory access violations)
What are the benefits of the first approach apart from not having to
free the pointer inside the struct ?
If by "first approach" you mean stack allocated array, then it's mainly the fact that you do not need to allocate anything and the stack does it for you (drawback being that it stays allocated in the declared scope and you can't free up or increase the array space) then the constant allocation speed and assurance you'll get your 100 array items no matter the OS response (many realtime applications require maximum response times, therefore a heap allocation can be a really big slowdown causing problems).
If by "first approach" you mean using the wrapper struct, then I do not see any benefits other than the one you already stated.
I'd even suggest you not advocate/use this approach, since it is a really confusing technique that doesn't serve noticeable benefits (plus it allocates 1 space even though it may not be even used, but that's a detail)
The main goal is to write code that is easily understandable by other people. Machines and compilers can nowadays do wonders with code, so unless you are a compiler designer, standard library developer or machine level programmer for embedded systems, you should write simple to understand code.
Given the following structure:
struct myStructure {
float myField;
};
struct mySecondStructure {
int myField;
struct myStructure *mySecondField;
};
How can I efficiently allocate the struct mySecondStructure on the heap? (With the variable mySecondField initialized to a valid memory address)
I came up with two ways doing this:
First approach: use two calls to malloc:
struct mySecondStructure *structure = malloc(sizeof(* structure));
structure->mySecondField = malloc(sizeof(* structure->mySecondField));
Second approach: use one call to malloc with enough space for both structures:
struct mySecondStructure *structure = malloc(sizeof(struct myStructure) + sizeof(struct mySecondStructure));
structure->mySecondField = (struct myStructure *)(((unsigned char *)structure) + sizeof(struct mySecondStructure)); // the pointer points now to the end of the first structure
But the first one is in my opinion inefficient since it uses two calls to malloc. However I'm not sure if the second one will work properly because of data alignment.
Can someone enlighten me about this?
I'm thankful for any given help.
The second approach should work; structs are padded so that they align properly (for example, consider if you had an array of them). One downside to the second approach would be if you wanted to reclaim the second structure (there is a reason its not just embedded in the first structure, I presume).
But the first is a lot cleaner, and what benefits there are to the second are minimal at best.
Both your approaches would work.
The difference between one malloc() call and two depends on how malloc() itself is implemented - which varies between implementations, is affected by operating system and hardware characteristics.
Without measuring the difference for your implementation, in the context of your program, and a typical execution environment (operating system, hardware, etc) all you are doing is indulging in premature optimisation.
Generally speaking, it would be better to do things in a way that are easier to understand (less complex code), easier to get right, and therefore easier to maintain. Then, if performance is a concern, do measurements to work out the bottlenecks.
In practice, you might also want to consider having a struct myStructure within your struct mySecondStructure, rather than a pointer [which is what Joachim's comment is about]. That way, you can allocate with a single malloc() call, without any need for additional bookkeeping to initialise pointers. Simpler to implement, easier to understand, and - if number of malloc() calls really matters - minimises that number.
Depending on the members of the structures, it's possible that they have different alignment requirements. With C11, these requirements can be inspected with _Alignof (also related: _Alignas, max_align_t, <stdalign.h>).
A portable solution (also for C99) would be to add padding manually, something along the following:
struct mySecondStructure *structure;
size_t secondAlign = sizeof *structure->mySecondField;
size_t offset = (sizeof *structure + secondAlign - 1) / secondAlign
* secondAlign;
size_t total = offset + sizeof *structure->mySecondField;
structure = malloc(total);
structure->mySecondField = (void *)((char *)structure + offset);
With C11,
size_t secondAlign = _Alignof(struct myStructure);
also yields a valid (possibly smaller) result.
Otherwise, I agree with the others' comments and answers that this looks like premature optimization. What perhaps could be done now, however, is thinking about how changes in the allocation strategy may influence other peaces of the code and trying to keep such inter-dependencies to a minimum in order to allow later changes if this turns out to be worth it (e.g. if it should be possible to partially release memory, as covered in Scott's answer).
So, I am creating a structure that currently needs a lot of memory. I hope to reduce it in the future, but for now, it is what it is. Hence, I need to allocate some of its elements on the heap because I get a stack overflow if they are put on the stack. And yes, I increased the stack size but on the target platform I only have so much.
In this case, would it be 'better' to allocate every structure element on the heap, or put some on the stack and the big stuff on the heap? For instance:
typedef struct my_structure_s{
int bounds[2];
int num_values;
int* values; //needs to be very large
} my_structure_t;
Vs:
typedef struct my_structure_s{
int* bounds;
int* num_values;
int* values;
} my_structure_t;
I know 'better' is largely subjective, and could quite possibly incite a riot here. So, what are the pros and cons of both examples? What do you usually do? Why?
Also, forgive the _s, _t stuff...I know some of you may find it in bad taste but that is the convention for the legacy codebase this will be integrated into.
Thanks everyone!
It is better to keep the simple members as direct values, and allocate just the array. Using the extra two pointers just slows down access for no benefit.
One other option to consider if you have C99 or C11 is to use a flexible array member (FAM).
You'd define your structure using the notation:
typedef struct my_structure_s
{
int bounds[2];
int num_values;
int values[];
} my_structure_t;
You'd allocate enough memory for the structure and an N-element array in values all in a single operation, using:
my_structure_t *np = malloc(sizeof(*np) + N * sizeof(np->values[0]));
This then means you only have to free one block of memory to free.
You can find references to the 'struct hack' if you search. This notation is effectively the standardized form of the struct hack.
In comments, the discussion continued:
This is an interesting approach; however, I can't guarantee I will have C99.
If need be, you can use the 'struct hack' version of the code, which would look like:
typedef struct my_structure_s
{
int bounds[2];
int num_values;
int values[1];
} my_structure_t;
The rest of the code remains unchanged. This uses slightly more memory (4-8 bytes more) than the FAM solution, and isn't strictly supported by the standard, but it was used extensively before the C99 standard so it is unlikely that a compiler would invalidate such code.
Okay, but how about:
typedef struct my_structure_s
{
int bounds[2];
int num_values;
int values[MAX_SIZE];
} my_structure_t;
And then: my_structure_t *the_structure = malloc(sizeof(my_structure_t));
This will also give me a fixed block size on the heap right? (Except here, my block size will be bigger than it needs to be, in some instances, because I won't always get to MAX_SIZE).
If there is not too much wasted space on average, then the fixed-size array in the structure is simpler still. Further, it means that if the MAX_SIZE is not too huge, you can allocate on the stack or on the heap, whereas the FAM approach mandates dynamic (heap) allocation. The issue is whether the wasted space is enough of a problem, and what you do if MAX_SIZE isn't big enough after all. Otherwise, this is much the simplest approach; I simply assumed you'd already ruled it out.
Note that every one of the suggested solutions avoids the pointers to bounds and num_values suggested in option 2 in the question.
do the first one. It is simpler and less error prone (you have to remember to allocate and release more things in the second one)
BTW - not that the first example will not put num_values on the stack. IT will go wherever you allocate the struct, stack, heap of static
As part of an assignment we have to implement a (basic) malloc function(we should somehow simulate dynamic memory allocation). I already implemented a solution based on implicit free list,but the problem is that i get a utilization of 50% and a throughput of 9% only(I have to get a 90% utilization+throughput). The problem with implicit free list is that it takes alot of time searching for free blocks. So i wanted to implement explicit free list to see how much can the program improve. now the problem is that i have to keep track of next/prev pointers for free blocks. And since I can only use scalar variables and cannot use any kind of data structures e.g:linked list,struct,.., i couldnt implement it. Can someone point out how can i keep track of (virtual) pointers in C?
thanks,
From the images in the slides (linked in the comments), I think you're expected to store the links as integer offsets.
In C, this really is best described as a struct.
struct alloc_cell {
int size;
int forward;
int back;
int data[];
};
Now, he also has the size repeated at the end, and that is much harder to describe with a struct. It's not clear how necessary it is. It's used for boundary coalescing.
Edit: much later, considering comment.
Even if you can't use structs in the code, you can still use them in the pseudocode to help organize your thinking. The struct fields, being all the same type, map naturally to an array
represention which can be accessed by a pointer to the the first member/element.
struct alloc_cell { // int *cell;
int size; // cell[0] // *cell
int forward; // cell[1]
int back; // cell[2]
int data[]; // (cell+3)[...] // &cell[3]
};
You could even go so far as to give these offsets mnemonic names (but this may be considered overkill and unnecessary obfuscation).
enum { SIZE, FORWARD, BACK, DATA };
cell[SIZE]; // alloc_cell.size
cell[FORWARD]; // alloc_cell.forward
cell[BACK]; // alloc_cell.back
cell+DATA; // &cell[DATA] // alloc_cell.data