How to perform deep copy at ADTs in C? - c

Recently, I am writing some Abstract Data Types (ADTs) for Queue in C Language.
But I found a problem for ADT in C:
How can I pass the type of data in C?
For example, in C++ I can use the template to pass type:
std::queue< struct mySt > myQ;
That template will pass "struct mySt" type to create myQ.
But how to do this in C?
All I know is to create a generic pointer pushing the data of "struct mySt" like below:
void enq(void *dataPtr);
and pop it using casting like below:
struct mySt *a = (struct mySt *) deq()
That seems work in C, but how can I perform "deep copy" action? I mean creating a new memory space for the content of the pointer dataPtr rather than just points it?
Except using Macro or Function pointer to solve this, is there other better way to solve it?

There isn't a simple way to do it in C. The C++ code relies on constructors (the copy constructor) to implement the copy, which is necessary because you can't tell a priori whether there are pointers in the class or allocated memory that need to be altered when an independent copy of the structure is made.
If you are going to copy the structures in a C ADT, then at a bare minimum you will need to specify the size of the structure to be copied as part of the interface. However, you really need a copy function that knows how to deal with the pointers in a copy of the structure.
Passing pointers around is simpler; it is clear that the object that is pointed at continues to exist unmodified by the fact that its pointer is now stored in a list.

Related

What is the best way to store integers with void pointers in C?

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.

C - memcpy and copying structs

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.

Deep copy a struct to another

I have a struct which contains strings and pointer within. Is there any library functions available to do a deep copy of the struct into another. I don't want to do a field by field copy since the struct I'm having is quite large.
Does glib have any function that does the trick?
No. A general-purpose function would have no way to know the structure of your struct (i.e. the information that's only available at compile time). And even if it did, how it would know what constitutes a "deep copy" in all circumstances?
You can use memcpy or memmove to copy the entire contents of the struct itself. However, as C has no introspection, copying pointed-to objects can't be done by a general purpose function.
Edited to add: As several commenters note, you can just assign structures to other structures in the C dialects in use for the last couple of decades, memcpy is not needed any longer.

Dynamically creating objects in C

Hello, guys!
I'm familiar with JavaScript and PHP, but new to C.
I am trying to play around with graphics in C and craete colision algorithm. Now, I need to create objects dynamically, just like in more advanced languages. For example, I need to create a polygon via my own function and make it an object that would be visible to the whole script. I assume, a struct would be needed.
As far as I know, everything declared in a function stays in a function. How can I dynamically declare global structs?
C is a fairly static language. By static I mean, you can create memory during run-time, but you will need pointers to address that memory declared at compile time. That is if you are going to need memory during run-time and do not want to declare it during compile time, you will need to use malloc and free (when you've finished with the memory).
To create a global structure whose memory you would create at run time, you would minimally need a pointer to a structure at compile time. If you need several of those structures, you could create several structures' worth of memory, but traversing the structures would be tedious without having an array of those structures. You would need that array of pointers to structures at compile time. There are some ways to make this more dynamic, but in decade or so I used C and C++, we never ran into those other ways, including in device drivers.
When you say create objects in C, you really have no objects you can create other than those created by a function call to a library or creating memory from the heap, and then interpreting that memory by overlapping structure or array pointers over it.
Functions can alter parameters if those parameters are passed in by reference (a pointer to the parameter), and functions can return nothing or return a single atom of data, a char, integer, smallint, or pointer.
a. function can return value.
b. you can use global variables.
c (and probably the most useful). dynamically allocate memory (using malloc,etc) and return pointer to it. (And remember to free it after using)
You need to have a struct or a more complex abstract data type (ADT) to hold your dynamically created variables. Once you have this, you can create the any object you want via malloc(), and store it in there.
As I mentioned earlier, it would be highly recommended to have a look at the ADTs and learn how to work with them. This will allow you to create any complex data structure like queues or linked lists in order to work a little more OOP oriented.
declare global pointers(array of pointers) of the same type as the structure. Use the functions like malloc etc. to dynamically allocate memory and assign it to the pointers.

Passing C struct pointer to lua script

I would like to know is there a way to pass a struct pointer to a lua script,
and reach it's members from lua without copy (for read and write purposes).
So, for example is it possible to overwrite a member of a c struct directly through of its pointer?
(I am using luajit)
In addition to Tim's answer, you can also go for light userdata. You don't end up with a copy of your data in the Lua stack, all you push to Lua is a pointer.
Lua has no understanding of what is in this pointer, whether it still points to valid memory, or how to access any objects in this pointer, so you'll have to handle all of this yourself in C. I am usually sending a pointer to an item on a list, so if there's any risk that entry has been deleted from the list, I first iterate over the list to validate the pointer (not a big deal if your lists are short). To access items within the pointer in Lua, you need to write get/set functions in C that you can call from Lua.
To get started, here are the entries on pushing and retrieving the lightuserdata:
lua_pushlightuserdata - push an entry on the stack
lua_touserdata - retrieve the pointer value
lua_islightuserdata - validate entry is light userdata
Programming in Lua entry on light userdata
Seeing as you have tagged this for luajit, you can combine the light userdata (as mentioned by others) with FFI for direct struct member access, see the tutorial here: http://luajit.org/ext_ffi_tutorial.html
The way to do this is with a lua userdata. Here are a couple examples: link, another link.

Resources