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.
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.
Recently I found it was annoyed to deal with array in c language.
I have to realloc() frequently to increase the size.
And there is no standard data structure like vector in C++ or Arraylist in java
I have got to known that in linux kernel, there is some data structure, such as kfifo,
we could use this by kfifo_in(), kfifo_out() function.
But this means the user would define kfifo *pointer; to record the array, and this variable does not contain any info about the type contained in the structure.
The user have to remember that when he try to use the dynamic array by kfifo pointer.
I think it may be a little confusing.
Is there any better way to deal with the problem? What's the common solution in linux c programing?
realloc is not that bad, as long as you do not spread it all over your code, and use a reasonable strategy to grow your dynamic array.
Rolling your own dynamic arrays in C is a matter of implementing a handful of easy functions. Numerous short articles walk you through this exercise - here is one for an example. The article defines a struct that represents your dynamic array, along with the currently used and the allocated size. It also provides functions for initializing, growing, and de-allocating the array represented by the structure. There is no explicit initialization function in the library - you initialize by passing NULL as the first parameter. This is a valid approach, but you could also opt for a more traditional separation of init and grow.
I'd use Glib arrays. It's a very well known library in Linux and other OSes, used in projects like Gnome.
There is no standard for dynamic arrays in C.
#bluesea
I mean they could define struct array{int len; int capacity; int each_element_size; void *data;} and copy the bytes of element, put at the end of the data. – bluesea Jun 29 at 3:04
This is already taken care of in the library under discussion. See the macro's that it comes with and the examples in the main.c file. Depending on the macros's being used, you would either end up with an array of pointers to the original data, or an array of pointers to a copy of the data.
FWIW, I'm the author of the library, and I'll be the first to admit that it comes without airbags, so you have to be sure to use it safely (as with anything else in C).
I have a program which creates a C structure which contains large arrays of various basic data types (ints doubles etc.). What is the most memory efficient way for me to return this data to Matlab from a C mexfunction, while also ensuring all of the memory deallocation is carefully taken care of? I would ideally like to return the whole structure, but methods for returning each array individually are also acceptable.
You may also assume I understand the basics of writing mexfunctions and returning arguments using the basic method of copying the data to an array pointed to by the plhs pointer. As I understand it, this will create a duplicate of the memory, i.e. requiring double the memory, correct me if this is incorrect.
My question has now been answered on another forum here. Below is the answer given:
"You cannot mix native C/C++ memory (i.e., local stack variables or allocated variables with malloc & cousins) into an mxArray for returning to the MATLAB workspace. That will eventually lead to crashing MATLAB when it tries to free this memory. So you are stuck with duplicating this memory. As I see it your options are:
1) Rewrite your code to create your C/C++ structure using MATLAB API functions mxMalloc & cousins instead of native C/C++ functions malloc & friends. Then this memory could be directly attached to an mxArray struct for returning to the MATLAB workspace ... no duplication or deallocation would be required.
2) Create your MATLAB struct piecemeal with mxMalloc & cousins as you deallocate the C/C++ memory piecemeal. This would still require you to duplicate the largest block temporarily, but saves you from duplicating everything in memory at the same time.
3) Ignore what I said about mixing native C/C++ memory and MATLAB API memory. Play games with hacking into the mxArray to mix them, keep shared data copies of them inside the mex routine to prevent MATLAB from attempting to free the memory. This is very tricky and is not recommended since you can easily leak memory and/or crash MATLAB if you don't manage everything correctly.
It doesn't save you any significant amount of memory returning several individual variables to MATLAB vs returning a struct or cell array, so just return whatever is easier to create and manage based on your intended use." -James Tursa
Hope my question makes sense:
Programming in C, can I create a hash table in a shared memory segment, so any process with proper permissions has access to the keys/values in it?
If so, how can I specify at hash table creation that I want it put in the SHM?
Is there any recommended hash table implementation that allows this?
Thanks a lot
Off the top of my head I don't know any libraries that do this.
I do know that if you write your own or modify an existing library, the tricky thing that you need to do is track down and fix any code that uses pointers and replace it with code that uses base + offset.
The base would be the pointer returned by the shared memory create/open functions and it will be different in each process. The offset replaces what would be a pointer. When you need to locate a value via offset, you cast base to char*, add the offset to that and then cast it to your_type*. Something like (bucket_t*)((char*)base + offset).
That's assuming your hash implementation needs pointers at all. Some don't if they only use single-value buckets and no value lists.
The other tricky thing is that you need to manage the memory yourself. Instead of calling malloc(), you make your own function, maybe name it shm_hash_alloc(). A quick start is to just keep a pointer and increment it when allocating memory and don't bother with freeing it. Later you can use an array of pointers(offsets) to free lists of various power of two sizes or if you know your object types, a list for each type. In each free block you store the pointer to the next free block and you know the size because of what list it's on. There are even fancier methods but you probably don't need them.
I uploaded a shared memory hash table library for linux to SF (libshmht), I developed it with the performance as main feature and read / write access homegeneous access time. I think it's usefull as cache and as IPC system.
Also implements read/write locks for sharing between many processes.
http://sourceforge.net/projects/libshmht/
Hash table is just a data structure. As long as the modules accessing the shared memory know how the structure is built, they can access it. It doesn't matter which implementation you use, as long as all the modules involved know how to read it.
Think of it as a newspaper. You create your own private memory segment - that's a town local paper. Then you want to share it with all the towns around - you can, as long as the people speak the same language and can read it. There's no special language for sharing, it just has to be the one everyone understands.
Same in your case - you can use any hash table implementation, as long as all the threads use the same.
I know its possible to increase the size of a dynamically allocated array.
But can I increase the size of a statically allocated array?
If yes,how?
EDIT: Though this question is intended for C language, consider other languages too.Is it possible in any other language?
Simple answer is no, this cannot be done. Hence the name "static".
Now, lots of languages have things that look like statically allocated arrays but are actually statically allocated references to a dynamically allocated array. Those you could resize.
in VB .NET it would be:
Redim Preserve ArrayName(NewSize)
not sure what langauge you're after though...
And I wouldn't use this command a lot... its terribly inefficient. Linked lists and growing data structures are much more efficient.
No. It is not. There are two options here:
Use a dynamic one
Or,at the risk of wasting memory, if you have an idea about the maximum number of elements that the array will store, statically allocate accordingly
Yes, that was C.
If you're careful, you can use alloca(). The array is allocated on the stack, but in terms of the code style it's a lot like if you used malloc (you don't have to free it though, that's done automatically). I'll let you decide whether to call that a "static" array.
No. Static allocation gives the compiler permission to make all kinds of assumptions which are then baked into the program during compilation.
Among those assumptions are that:
it is safe to put other data immediately after the array (not leaving you room to grow), and
that the array starts at a certain address, which then becomes part of the machine code of the program; you can't allocate a new array somewhere (and use it) because the references to the address can't be updated.
(Well, references could be updated, if the program was stored in ram, but self-modifying programs are highly frowned upon, and surely more trouble than dynamic arrays.)
Technically, in C it isn´t even possible to increase the size of a dynamically allocated array.
In fact, realloc() does some kind of "create new object & copy the data" routine. It does not modify the size of an existant heap-memory object at all.
So the answer is simple as that, that you are not be able to change the size of any object or array of objects after it has been allocated, neither if it was dynamically or statically allocated.
What you can do is to use the same strategy by developing a function which is creating another static allocated array of objects with the desired size and copy the data. If the new array of objects is smaller than the old one, the values inside the difference are discarded.
The only difference is, that the size of the new array, equivalent to the size of the old array, need to be fixed at compile-time.