Ran into a design problem when using memcpy and building a generic HashTable in c. The HashTable maps unsigned int keys to void * data that I memcpy over.
// Random example
void foo() {
// Suppose `a` is a struct that contains LinkedLists, char arrays, etc
// within it.
struct *a = malloc(sizeof(a));
HashTable ht = ht_create(sizeof(a));
// Insert the (key, value) pair (0, a) into the hash table ht
ht_insert(ht, 0, a);
// Prevent memory leak
destroy_struct(a);
// Do stuff...
// ... eventually destroy ht
ht_destroy(ht);
}
Now, given struct a has LinkedLists and pointers within it, and the HashTable is using memcpy, my understanding is that it copies over shallow copies of these pointers. Thus, ht_insert mallocs space for a new entry, shallowly copies over data from a, and inserts the new entry into its table.
Consequently, unless I free struct a completely with some function destroy_struct, I am leaking memory. However, given I'm shallowly copying data in ht_insert, when I call destroy_struct(a), I will have accidentally freed the data pointed to within the hash table's entry as well!
Is the logic above correct, and if so, should I use a some recursive memcpy function that makes sure to deep copy all data from struct a to the HashTable?
Firstly, if your code doesn't reproduce the problem you are explaining, you shouldn't include it. The problem your code produces is compiler errors. This doesn't help your question, does it?
Now, given struct a has LinkedLists and pointers within it, and the HashTable is using memcpy, my understanding is that it copies over shallow copies of these pointers.
If you are simply copying the internal representation of a struct whatever * into the internal representation of a void *, then you are asking for trouble. There is no guarantee that the two representations are identical. It's possible that one pointer type might be larger than the other, that they use different endianness (if they're implemented as typical quasi-integers) or other internal differences might exist. You should convert one pointer to the other type, and then you could simply assign it... In fact, because one of the types is void * that conversion will happen implicitly when you assign.
Consequently, unless I free struct a completely with some function destroy_struct, I am leaking memory.
From what you have described, you should only call free on that pointer value once (and only once) you are done with it, and your program no longer has any use for it (e.g. after you have removed it from the hashtable). This goes for all non-null pointers that are returned by malloc, realloc or calloc. To clarify: if x and y store the same pointer returned by one of those functions, free should only be called ONCE on ONE OF THEM because they contain the same value.
Is the logic above correct, and if so, should I use a some recursive memcpy function that makes sure to deep copy all data from struct a to the HashTable?
I highly recommend breaking this question up into two or more separate questions, because it's double-barreled. I could simply answer "yes" (or "no"). Would that give you any meaningful information?
This brings me back to what I first wrote. I can only guide you based on what you've written here, which might not be reflective of the code that you use (especially given the influences of the erroneous code you've given). In order to guide you better, I would need to see all of the gaps filled in. I would need to see a testcase that creates a hashtable, inserts into the hashtable, uses the hashtable, removes from the hashtable and cleans up the hashtable to determine whether or not your operations are leaking anywhere... but most importantly, this testcase would need to be COMPILABLE! Otherwise it can't do any of those things, because it can't compile.
Related
Hello i am trying to learn and build data structures in c and i want to store integers progressively in the stack.
my struct is like this:
typedef struct STACK_NODE_s *STACK_NODE;
typedef struct STACK_NODE_s{
STACK_NODE forward;
void *storage;
} STACK_NODE_t;
typedef struct L_STACK_s{
STACK_NODE top;
} L_STACK_t, *L_STACK;
In a while loop i want to read and store my chars in integer form.
//assume that str is an proper string
//assume that we have a linked stack called LS
int i=0;
int temp;
while(str[i]!='\0'){
tmp=str[i]-'0';
push(LS,(void *)&tmp);
}
I know this won't work properly as we store the same variable's adress over and over again.
Do i need to allocate an auxiliary array in order to store them 1 by 1 or is there a better way to do this?
The answer must address two separate aspects of your question:
How to organize some collection of items, and where to get the memory from to do that.
First code snippet / Linked list format
The first code snippet is good the way it is.
It sets up a linked list, which has its pros and cons, but serves very well if you don't know the number of items in advance, if you want to be able to quickly remove or insert items somewhere in the middle of the list, and if you don't mind that looking up one certain entry inside the list costs you O(N) effort.
For a generic library-like implementation...
... void* is as good as it goes with ANSI C.
In C++, for example, you could make a template that leaves open the type that is stored in the list (or better yet, you would directly reuse the well-known STL implementation in class forward_list<int>).
Sadly, ANSI C doesn't have something comparable.
One solution is the one you picked, create int objects and hook their addresses into your list of void*.
Another solution for a generic library implementation is to use a precompiler macro for the type, and to define this macro above a header file that holds the generic implementation. This tries to resemble the clean C++ solution, but with precompiler it is not typesafe, so this approach is far from beautiful and comes with several risks.
Second code snippet / Memory allocation
Creating the list with void* instead of int (or whatever non-pointer type) requires you to allocate further memory beside the list.
I. e., it is not only that you have to allocate every list item (= variable of type STACK_NODE_t) but also the actual entry value (e. g., *(int*)(LS->storage)).
This means you have to allocate/deallocate the data in some other way that outlives the stack.
On most systems, you can use malloc/free for that, and you only have to take into account the size of the heap available for malloc and the time de-/allocating takes.
If the list shall implement real-time requirements or on embedded systems, you may not have malloc or you may not be allowed to use it.
Then you have to allocate and implement your own heap (= memory pool of storage items) for your list.
How to implement such a memory pool with desired properties is a separate question that would take us to far here.
In any case, you must not use the pointer to a stack variable (like a local variable inside a function) because the memory "behind" that variable will not be reserved for this purpose once the function exits, and the memory may be used for something different in the meantime.
This is, however, what the second code snippet does apparently.
As you noticed yourself, taking this path...
we store the same variable's adress over and over again.
Reusing the memory position for another entry of the same list is an extreme case of the risk explained above.
I solved the problem using an auxiliary array like i anticipated. If someone comes up with a better solution its more than welcome.
I'm new to C (and structures in C). And I've seen varying code examples across the internet, but what is the benefit of doing this:
void foo(LargeStruct* struct);
instead of this
void foo(LargeStruct struct);
Does it make memory management easier?
The former passes a pointer to the structure to the function. The latter makes a copy of the structure and passes it to the function. If the structure is large, making a copy of it for the function is expensive (uses lots of resources), so it should be avoided unless it's necessary.
C passes structs by value. What it means is that the function with the second signature would make a copy of the entire LargeStruct in order to pass it to foo. This is not economical in terms of memory use.
What's worse, the allocation of LargeStruct would happen in automatic memory (also known as "on the stack"). Depending on the actual size of your struct, the call may not be possible on some systems, because it would cause stack overflow.
The first approach, on the other hand, passes the struct by pointer. Pointer's size does not depend on the size of LargeStruct.
Since C is passing arguments by value, there are two major points:
In function body, you will receive a copy of the parameter passed in, so in the case of void foo(LargeStruct struct);, you get a copy of the struct, when you modify the members of the struct, it's actually not seen outside, because it's a temporary copy, which is destroyed when the function returns. So if you want to modify a struct, you will have to pass in a pointer to that struct.
Since arguments are copied and if the struct is really large, there is some memory overhead. In this if you don't want to modify the struct, just to minimize the memory overhead, you can pass a const pointer:
foo(const LargeStruct *p);
A struct can be either passed/returned by value or passed/returned by reference (via a pointer) in C.
The general consensus seems to be that the former can be applied to small structs without penalty in most cases. See Is there any case for which returning a structure directly is good practice? and Are there any downsides to passing structs by value in C, rather than passing a pointer?
And that avoiding a dereference can be beneficial from both a speed and clarity perspective. But what counts as small? I think we can all agree that this is a small struct:
struct Point { int x, y; };
That we can pass by value with relative impunity:
struct Point sum(struct Point a, struct Point b) {
return struct Point { .x = a.x + b.x, .y = a.y + b.y };
}
And that Linux's task_struct is a large struct:
https://github.com/torvalds/linux/blob/b953c0d234bc72e8489d3bf51a276c5c4ec85345/include/linux/sched.h#L1292-1727
That we'd want to avoid putting on the stack at all costs (especially with those 8K kernel mode stacks!). But what's about middling ones? I assume structs smaller than a register are fine. But what about these?
typedef struct _mx_node_t mx_node_t;
typedef struct _mx_edge_t mx_edge_t;
struct _mx_edge_t {
char symbol;
size_t next;
};
struct _mx_node_t {
size_t id;
mx_edge_t edge[2];
int action;
};
What is the best rule of thumb for determining whether a struct is small enough that it's safe to pass it around by value (short of extenuating circumstances such as some deep recursion)?
Lastly please don't tell me that I need to profile. I'm asking for a heuristic to use when I'm too lazy/it's not worth it to investigate further.
EDIT: I have two followup questions based on the answers so far:
What if the struct is actually smaller than a pointer to it?
What if a shallow copy is the desired behavior (the called function will perform a shallow copy anyway)?
EDIT: Not sure why this got marked as a possible duplicate as I actually link the other question in my question. I'm asking for clarification on what constitutes a small struct and am well aware that most of the time structs should be passed by reference.
On small embedded architectures (8/16-bitters) -- always pass by pointer, as non-trivial structures don't fit into such tiny registers, and those machines are generally register-starved as well.
On PC-like architectures (32 and 64 bit processors) -- passing a structure by value is OK provided sizeof(mystruct_t) <= 2*sizeof(mystruct_t*) and the function does not have many (usually more than 3 machine words' worth of) other arguments. Under these circumstances, a typical optimizing compiler will pass/return the structure in a register or register pair. However, on x86-32, this advice should be taken with a hefty grain of salt, due to the extraordinary register pressure a x86-32 compiler must deal with -- passing a pointer may still be faster due to reduced register spilling and filling.
Returning a structure by value on PC-likes, on the other hand, follows the same rule, save for the fact that when a structure is returned by pointer, the structure to be filled out should be passed in by pointer as well -- otherwise, the callee and the caller are stuck having to agree on how to manage the memory for that structure.
My experience, nearly 40 years of real-time embedded, last 20 using C; is that the best way is to pass a pointer.
In either case the address of the struct needs to be loaded, then the offset for the field of interest needs to be calculated...
When passing the whole struct, if it is not passed by reference,
then
it is not placed on the stack
it is copied, usually by a hidden call to memcpy()
it is copied to a section of memory that is now 'reserved'
and unavailable to any other part of the program.
Similar considerations exist for when a struct is returned by value.
However, "small" structs,
that can be completely held in a working register to two
are passed in those registers
especially if certain levels of optimization are used
in the compile statement.
The details of what is considered 'small'
depend on the compiler and the
underlying hardware architecture.
Since the argument-passing part of the question is already answered, I'll focus on the returning part.
The best thing to do IMO is to not return structs or pointers to structs at all, but to pass a pointer to the 'result struct' to the function.
void sum(struct Point* result, struct Point* a, struct Point* b);
This has the following advantages:
The result struct can live either on the stack or on the heap, at the caller's discretion.
There are no ownership problems, as it is clear that the caller is responsible for allocating and freeing the result struct.
The structure could even be longer than what is needed, or be embedded in a larger struct.
How a struct is passed to or from a function depends on the application binary interface (ABI) and the procedure call standard (PCS, sometimes included in the ABI) for your target platform (CPU/OS, for some platforms there may be more than one version).
If the PCS actually allows to pass a struct in registers, this not only depends on its size, but also on its position in the argument list and the types of preceeding arguments. ARM-PCS (AAPCS) for instance packs arguments into the first 4 registers until they are full and passes further data onto the stack, even if that means an argument is split (all simplified, if interested: the documents are free for download from ARM).
For structs returned, if they are not passed through registers, most PCS allocate the space on the stack by the caller and pass a pointer to the struct to the callee (implicit variant). This is identical to a local variable in the caller and passing the pointer explicitly - for the callee. However, for the implicit variant, the result has to be copied to another struct, as there is no way to get a reference to the implicitly allocated struct.
Some PCS might do the same for argument structs, others just use the same mechanisms as for scalars. In any way, you defer such optimizations until you really know you need them. Also read the PCS of your target platform. Remember, that your code might perform even worse on a different platform.
Note: passing a struct through a global temp is not used by modern PCS, as it is not thread-safe. For some small microcontroller architectures, this might be different, however. Mostly if they only have a small stack (S08) or restricted features (PIC). But for these most times structs are not passed in registers, either, and pass-by-pointer is strongly recommended.
If it is just for immutability of the original: pass a const mystruct *ptr. Unless you cast away the const that will give a warning at least when writing to the struct. The pointer itself can also be constant: const mystruct * const ptr.
So: No rule of thumb; it depends on too many factors.
Really the best rule of thumb, when it comes to passing a struct as argument to a function by reference vs by value, is to avoid passing it by value.
The risks almost always outweigh the benefits.
For the sake of completeness I'll point out that when passing/returning a struct by value a few things happen:
all the structure's members are copied on the stack
if returning a struct by value, again, all members are copied from the function's stack memory to a new memory location.
the operation is error prone - if the structure's members are pointers a common error is to assume you are safe to pass the parameter by value, since you are operating on pointers - this can cause very difficult to spot bugs.
if your function modifies the value of the input parameters and your inputs are struct variables, passed by value, you have to remember to ALWAYS return a struct variable by value (I've seen this one quite a few times). Which means double the time copying the structure members.
Now getting to what small enough means in terms of size of the struct - so that it's 'worth' passing it by value, that would depend on a few things:
the calling convention: what does the compiler automatically save on the stack when calling that function(usually it's the content of a few registers). If your structure members can be copied on the stack taking advantage of this mechanism than there is no penalty.
the structure member's data type: if the registers of your machine are 16 bits and your structure's members data type is 64 bit, it obviously won't fit in one registers so multiple operations will have to be performed just for one copy.
the number of registers your machine actually has: assuming you have a structure with only one member, a char (8bit). That should cause the same overhead when passing the parameter by value or by reference (in theory). But there is potentially one other danger. If your architecture has separate data and address registers, the parameter passed by value will take up one data register and the parameter passed by reference will take up one address register. Passing the parameter by value puts pressure on the data registers which are usually used more than the address registers. And this may cause spills on the stack.
Bottom line - it's very difficult to say when it's ok to pass a struct by value. It's safer to just not do it :)
Note: reasons to do so one way or the other overlap.
When to pass/return by value:
The object is a fundamental type like int, double, pointer.
A binary copy of the object must be made - and object is not large.
Speed is important and passing by value is faster.
The object is conceptually a smallish numeric
struct quaternion {
long double i,j,k;
}
struct pixel {
uint16_t r,g,b;
}
struct money {
intmax_t;
int exponent;
}
When to use a pointer to the object
Unsure if value or a pointer to value is better - so this is the default choice.
The object is large.
Speed is important and passing by a pointer to the object is faster.
Stack usage is critical. (Strictly this may favor by value in some cases)
Modifications to the passed object are needed.
Object needs memory management.
struct mystring {
char *s;
size_t length;
size_t size;
}
Notes: Recall that in C, nothing is truly passed by reference. Even passing a pointer is passed by value, as the value of the pointer is copied and passed.
I prefer passing numbers, be they int or pixel by value as it is conceptually easier to understand code. Passing numerics by address is conceptual a bit more difficult. With larger numeric objects, it may be faster to pass by address.
Objects having their address passed may use restrict to inform the function the objects do not overlap.
On a typical PC, performance should not be an issue even for fairly large structures (many dozens of bytes). Consequently other criteria are important, especially semantics: Do you indeed want to work on a copy? Or on the same object, e.g. when manipulating linked lists? The guideline should be to express the desired semantics with the most appropriate language construct in order to make the code readable and maintainable.
That said, if there is any performance impact it may not be as clear as one would think.
Memcpy is fast, and memory locality (which is good for the stack) may be more important than data size: The copying may all happen in the cache, if you pass and return a struct by value on the stack. Also, return value optimization should avoid redundant copying of local variables to be returned (which naive compilers did 20 or 30 years ago).
Passing pointers around introduces aliases to memory locations which then cannot be cached as efficiently any longer. Modern languages are often more value-oriented because all data is isolated from side effects which improves the compiler's ability to optimize.
The bottom line is yes, unless you run into problems feel free to pass by value if it is more convenient or appropriate. It may even be faster.
We do not pass structs by value, neither we use naked pointers (gasp!) all the time and everywhere. Example.
ERR_HANDLE mx_multiply ( MX_HANDLE result, MX_HANDLE left, MX_HANDLE right ) ;
result left and right are instances of the same (struct) type for 2D matrix
multiply is some other error (struct) type
'handle' is the address of the struct on the memory 'slab' pre-allocated for the instances of the same types
is this safe? Very. Is this slow? A bit slower vs naked pointers.
in an abstract way a set of data values passed to a function is a structure by value, albeit undeclared as such.
you can declare a function as a structure, in some cases requiring a type definition. when you do this everything is on the stack. and that is the problem. by putting your data values on the stack it becomes vulnerable to over writing if a function or sub is called with parameters before you utilize or copy the data elsewhere. it is best to use pointers and classes.
I'm working in a small C program and I need to embed binary data into an exe file. The method I'm using is converting that binary data into a char[] array... but I'm not including directly that array as a global variable; instead, I copy that array inside a function (LoadResource) that dynamically creates an array on heap, where I copy my original data. That's what I mean:
char *dataPntr;
void LoadResource()
{
char data[2048] = {/*my binary data */};
dataPntr = malloc(2048);
for (int i = 0; i < 2048; i++) dataPntr [i] = data[i];
}
That way, if my understanding is correct, when calling LoadResource() data[] will be placed in stack, copied to heap and finally data[] will be automatically deallocated from stack; heap copy should be manually deallocated with free().
I'm doing it this way because the resource is only used in some situations, not always... and I prefer to avoid a large global variable.
My questions:
When running the program, is data[] array placed somewhere in memory? text segment maybe? or is it just loaded into stack when calling LoadResource()?
Is my solution the proper one (in terms of memory management) or would it be better to just declare a global data array?
Thanks for your answers!
Generally it is a good idea to avoid global variables. I won't say you never need them, but they can be a pain to debug. The problem is that it can be difficult to follow who changed it last. And if you ever do any multi-threading then you will never want to see a global again!
I include your char *dataPntr in those comments - why is that global? It might be better to return the pointer instead.
Not sure why you are using an array on the stack (data), my guess is so that you can use the {...} initialisation syntax. Can you avoid that? It might not be a big deal, 2k is not a large overhead, but maybe it might grow?
Personally I would copy the data using memcpy()
You have a couple of "magic numbers" in your code, 2048 and 2018. Maybe one is a typo? To avoid this kind of issue, most will use a pre-processor macro. For example:
#include <string.h> /* for memcpy() */
#define DATA_SIZE 2048
char * LoadResource(void)
{
char data[DATA_SIZE] = {/*my binary data */};
char * dataPntr = malloc(DATA_SIZE);
if (dataPntr)
memcpy(dataPntr, data, DATA_SIZE);
return dataPntr;
}
By the way, notice the prototype for LoadResource as void. In C (not C++) an empty parameter list means no parameter checking, not no parameters. Also note that I check the returned value from malloc. This means that the function will return NULL on error.
Another strategy might be to make the data array static instead, however exactly when that gets initialised is compiler dependant, and you might find that you incur the memory overhead even if you don't use it.
While I agree with #cdarke in general, it sounds to me that you are creating a constant array (i. e. is never modified at run-time). If this is true, I would not hesitate to make it a global const array. Most compilers will simply place the array in text memory at link time and there will not be any run-time overhead for initialization.
If, on the other hand, you need to modify the data at run-time, I'd follow #cdarke's example, except to make your data array static const. This way, again, most compilers will place the preinitialized array in the text segment and you will avoid the run-time overhead for initializing the data array.
In a separate library, we have a struct with:
typedef struct bsmat{
int m;
int *n;
double **d;
} bs;
where **d is a array of pointers to double arrays.
bs *new_bs(int n, double **d);
There are two use cases:
(a) The main application allocates multiple double matrices and calls the library to construct the structure.
b = new_bs(5, p)
(b) Alternatively, an object may be generated by the library as a result of a call to a function:
bs *add(bs *a, bs *b);
In the second case, the library owns **d and can free it when necessary. In the first case, the application has allocated the array and the library may read from/write to it. It is not clear to me as to who should free what and when??
Is it a problem to allow the main application to own a struct-member? What are the problems with this approach? What are the alternatives? We are trying to avoid copying large number of arrays back-and-forth.
thanks
TR
In general, it's important that the library documents the 'contract' it makes with the applications that are using its service. The library writer documents all the allocations made by the library and what needs to be freed by the application. Like any contract, it's good when it is simple and consistent.
In this particular case, I suppose the library should also offer:
void free_bs(bs *b)
{
if (b->d) {
/* free b->d here */
}
/* free rest of the structure */
}
which frees the structure. It makes sense to also free the d array here. The application has pointer to all the bs structures and is responsible for calling free_bs on them when no longer needed.
If, for example, you want to keep d for future usage, after you're done with the library operation, the contract is a bit more complex. The library could also provide:
double** bs_get_data(bs *b)
{
double **d = b->d;
b->d = NULL;
return b->d;
}
which returns a pointer to d, and leaves the field empty so that the free routine knows to skip it.
The docs for the bs_get_data() have to explain that it can be called only once, and that the application takes the responsibility of freeing the array in this case.
UPDATE:
In answer to your comment below: First of all, please note that I simplified the problem by assuming (at least) the following: the d is referenced either by a single bs structure or by the application. The application and the library "pass" a single reference to the array from one to the other. If you want the same d array in more bs structures, for example, than my approach is not enough.
The flag that you propose in the comment might help, but is not standard practice, FWIK. In this case, I would suggest to implement some simple reference counting. If d is the resource that needs to be shared around, make it an "object":
typedef struct {
double **d;
int ref;
} d_t;
Initialize ref with 1. In new_bs() and in all functions that receive a "copy" of d, increment the reference count. When the bs structure gets deleted, or when you no longer need d in your application, decrement it's reference count. If it gets to zero, free it. In a way, it is what the high level languages do for you, and is very efficient in keeping the resource management sane.
So no one is owning the array, but whoever needs it last, frees it.
Of course, this requires more work and complicates code, so try to put in balance. It's not needed for every structure you have, but only for those you need to keep multiple references to.
I think reference counting is overkill for this problem. But your interface needs to specify more precisely who owns *b and not just b->d. It's not at all clear to me how the library knows when it is "necessary" (as you put it) to free b->d.
I'd extend the interface as follows:
Every pointer of type bs * is either externally managed or internally managed. Function new_bs returns an externally managed pointer; function add returns an internally managed one.
Every function that returns a pointer of type bs * should say whether the management of the result is internal or external.
You probably should provide functions
void bs_free_ext(bs **); // free *bs and set *bs = NULL (external mgmt)
void bs_free_int(bs **); // free *bs and set *bs = NULL (internal mgmt)
bs_free_ext frees only *bs; bs_free_int frees both *bs and (*bs)->d.
For safety's sake I would also add the field that records the storage management of each struct, and I would have assertions on any function that allocates or frees. (Reason: assertion checking is cheap compared to the cost of allocating or freeing.)
If you can run your app on Linux then memory checking with valgrind is a plus.
P.S. The fact that details of memory management leak into almost every interface is one of the costs we pay to get the benefits of programming in C.