I'm working with shared memory and I need several pointers for my program, but I have the restriction to use only one identifier:
int idSh;
int * mem;
char * mem2;
idSh = Shmget (IPC_PRIVATE, sizeof (char *) + sizeof (int *), IPC_CREAT | 0700);
mem = Shmat (idSh,0,0);
mem2 = Shmat (idSh,0,0);
I have to use several pointers with Shmat but I only have one segment of shared Memory with the identifier idSh.
Any solutions?
You need to rewrite your ‘pointer based’ data structures to be ‘offset based’, and make a sort of directory at the beginning of your shared memory object. The directory should identify the offsets to the root data structures, so each accessor can adapt to whichever address it is mapped at. The bad news is that it is a lot of fiddly work; the good news is it usually makes source bases better. Offset based has all sorts of advantages, such as being able to take a snapshot of the whole data structure, and write utilities that can analyze it off line.
Offset Based: if you had a node in a linked list like:
struct Node {
MyType Data;
struct Node *Link;
}
you would need to change it to something like:
struct Node {
MyType Data;
uintptr_t Link;
}
Then walking your data structure looks something like:
extern uintptr_t ShmemBase;
struct Node *Next = (struct Node *)(ShmemBase + Cur->Link);
although I bet you could do a much better job of encapsulating this, maybe even associated the “Link” field with the particular shared memory object.
I’ve done these transformations in the past, and they typically aren’t as bad as you might imagine. You do develop an appreciation for people who hide the data structure access methods properly....
Alternately, systems can often be coerced into mapping objects at a unified address for all participants; so if you hack around with your target system for a bit, you might find these magic addresses. Eventually, somebody will hate you if you go this route.
Related
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.
I have to create for academic purpose an "On-Demand Server" that is based on the TCP protocol. The client each time sends a KEY and a VALUE that I have to store them in a global struct like the one bellow:
I use a function named "put" to store every KEY and VALUE to the struct and a "get" function that uses the key and finds the correct value:
My problem is that if a client makes a change in the struct the next one won't be able to know. I used semaphores in order to make the server wait until the child finishes and then accept the next child but I have still the same problem.
I read that I have to make the memory of this struct shared in order to make this work using mmaps but still I can't find a proper solution.
I make my first steps in server programming and every help would be great.
My problem is that if a client makes a change in the struct the next one won't be able to know.
As you noted, mmap() is part of the solution...
Shared memory needs of your application can be addressed with _shm_open()_, _shm_unlink()_, mmap etc. as illustrated in this post. And here for additional examples on shared memory
All of the essentials are summarized in the links, but this excerpt describes the basic concept:
shm_open() creates and opens a new, or opens an existing, POSIX
shared memory object. A POSIX shared memory object is in effect a
handle which can be used by unrelated processes to mmap(2) the same
region of shared memory. The shm_unlink() function performs the
converse operation, removing an object previously created by
shm_open().
I also wanted to suggest that dynamic allocation of memory may be of use in creating space for your struct on an as-needed basis. The size of members, as shown are excessively large,
char keys[4096];
char values[4096];
but in comments you state they only need to be 51 bytes. The struct then can be created as a typedef:
struct keyvalue {
char keys[51];
char values[51];
} DATA;
The create an instance of a pointer to your struct:
DATA *pData = {0};
Which can then be sized on an as needed basis using standard malloc, and or realloc
pData = malloc(initialSize*sizeof(DATA));
As size requirements change, use the following to grow memory:
DATA *tmp = {0};
tmp = realloc(pData, newSize);
if(!tmp) return -1;//ensure memory allocation successful
pData = tmp;//tmp includes previous contents of pData, and more space
... //continue using pData
Free pData when it is no longer needed.
free(pData);
To pass this struct in a function, the function might look like this:
void func1(DATA *d, int numElements)
{
...
for(i=0;i<numElements;i++)
{
strcpy(d[i]->keys, "some key");
strcpy(d[i]->values, "some value");
}
...
}
To call that function with a copy of pData, if say it had a 1000 elements:
func1(pData, 1000);
I'm currently making a RedBlackTree in C and I still don't understand which one is better / more ideal when it comes to having a constuctor function for your structures.
struct RedBlackTree* RedBlackTree_new()
{
struct RedBlackTree *tree = calloc(1, sizeof(struct RedBlackTree));
if (tree == NULL)
error(DS_MSG_OUT_OF_MEM);
return tree
}
VS.
struct RedBlackTree RedBlackTree_new()
{
struct RedBlackTree tree;
tree.root = NULL;
tree.size = 0;
return tree;
}
I mean, if I do the second option, then I constantly have to pass it into my functions as a pointer using & and to my knowledge, I can never destroy it until my program ends (can someone verify if that's true?). For example, if I had adestroy function for my Tree, I wouldn't be able to free the memory allocated from structures within the RedBlackTree if they weren't created with malloc or calloc right?
Also in a more general case, what are the advantages and disadvantages of either? I can always retrieve the data from the pointer by using * and I can always turn my data into a pointer by using &, so it almost feels like they are completely interchangable in a sense.
The real difference is the lifetime of the object. An object allocated on heap through dynamic allocation (malloc/calloc and free) survives until it's explicitly freed.
On the contrary an object which has automatic storage, like in your second example, survives only the scope in which it's declared and must be copied somewhere else to make it survive.
So this should help you in choosing which suits better a specific circumstance.
From an efficiency perspective dynamic allocation is more expensive and requires additional indirections but allows you to pass pointers around, which prevents data from being copied thus can be more efficient in other situations, eg. when objects are large and copies would be expensive.
firstly it's better to use typedef. it's easier.
if u create an object dynamically, u need to free every member of the object urself. or, the memory leak.
if it is a big struct , when u return it, it create a temp object. it cost more. so I prefer pointer!
and forget what i say before. I just sleepwalking.
I wrote a Linked List ADT for a class I am in originally for a list of ints. Now I am going to use the same list for chars and ints. I know how to rewrite the code for chars to just have basically two List ADTs, one for the ints and the other for the chars.
I don't want to do that however, I want to write it for a generic variable so that in the future I can use this ADT with other code without worrying about types to much.
Initially I went into this with void*, but I am running into an error with it that I am just have a hard time understanding how to fix.
typedef struct NodePtr {
void* data;
struct NodePtr*next;
struct NodePtr*prev;
} NodePtr;
typedef struct ListStruct {
NodePtr* first;
NodePtr* last;
NodePtr* current;
} ListStruct;
Then some other code and fun stuff, and then my insert method to insert at the front of the list:
void insert(listhndl L, void* data)
{
...inserting of the node here.
}
This code throws no error, but then when I run a driver to test it:
ListHndl test = NULL;
test = newList();
insert(test, 1);
I get the error message:
warning: passing argument 2 of 'insert' makes pointer from integer without a cast [enabled by default]
insert(test, 1);
^
error: expected 'void *' but argument is of type 'int'
void insert(ListHndl L, void* data);
I am confused here because how can it throw an error saying it's not the type it expected, if void* is a generic type?
What am I doing wrong?
I saw on here some people recommend using enum and unions for generics instead of void*, but I could not get that to work ether as I don't really understand what to do with them. If somebody wanted to also answer how to do generics with the enums/unions method I would greatly appreciate it.
Your list addition parameter is a void* so naturally you'll be flagged with an implicit conversion warning (or error if you're compiling with -Wall -Werror like you should be). Generic implementations of any node management algorithms isn' a trivial as it may seem, and much has been written/coded on the subject.
In your case, you could dynamically allocate the data being added yourself (i.e. allocate an int and send the resulting address as the void*, or create additional parameterization of your list interface functions and make them smart enough to figure out what to allocate (if anything)
In general, a generic linked list is eventually not going to escape ownership and sizing information if you're planning on using pointers (and all of the samples linked below go to some lengths to accommodate this). An elaborate enough interface capable of constituting this information into a reasonable node architecture that is generic enough is tedious, but that is the price you pay for generics. Performance is likewise a factor, and again, pay the piper. Type information for a list that holds different data types may also be a consideration, in particular if you're inclined in your algorithms to minimize memory management usage.
There are a multitude of generic linked lists sourced all over this grand illusion we call the World Wide Web. Here are a few such implementations:
PseudoMuto Generic Linked List : Assumes all items are the same size, maintains dynamic storage to them via internal memory management.
CMU Generic Linked List: lecture notes on generics development.
Uncredited Generic List (circa 1999): Another fixed size dynamically managed linked list. Not particularly impressive, but at least functional.
Atachil's Generic Linked List: Yet another generic implementation, this one implemented as a double-linked list.
Plenty more where that came from (google and 10 minutes of filtering out junk).
You needn't reinvent the wheel, but if you want to there are plenty of examples out there that can assist you. A challenge would be implementing a list that
Takes user-provided allocation/deallocation functions for any memory management requirements
Uses a union internal to the list_node that supports all the fundamental data types as well as a void* and size_t for blob or string data, and of course, a type-identifier so you know what member is the member.
Provides dynamic ownership semantics (i.e. allows the client to specify a dynamic node pointer is "owned" by the client and to not store a duplicate; just use the provided data pointer.
Bi-directional management (i.e. a double linked list)
Just a few things to consider when embarking on your quest. I wish you the best of luck.
You can make the type of data to be handled more opaque by encapsulating it into a typedef:
typedef struct my_opaque_data {
int item; /* example opaque data */
} DATA;
struct NodePtr {
DATA data;
struct NodePtr *next, *prev;
} NodePtr;
So far, all I have done is replace void * with DATA.
Then you will probably want to declare some basic operations to be implemented elsewhere to handle the type:
extern int data_compare (const DATA *left, const DATA *right); /* return < 0 if left < 0, 0 if equal, etc. */
extern void data_set (DATA *dest, const DATA *src); /* *dest = *src */
extern void data_swap (DATA *d1, DATA *d2); /* exchange *d1 and *d2 */
extern size_t data_size (const DATA *d); /* return size (bytes) of *d */
...
Each of these is almost certainly trivial to implement, but by substituting different data types, even complex data types, in DATA, the source code can remain complete generic and oblivious to what is in DATA. With this one could easily implement list operations, sorting, searching, etc., etc.
I'm stuck on understanding what's happening with this struct (from C for Programmers a Deitel book).
The book says, "A structure cannot contain an instance of itself. For example, a variable of type struct employee cannot be declared in the definition for struct employee. A pointer to struct employee, however, may be included."
It then gives the following example:
struct employee2 {
char firstName[ 20 ];
char lastName[ 20 ];
unsigned int age;
struct employee2 *ePtr;
};
I don't understand what this is doing, and I don't understand the reference to struct employee without the 2.
How does struct employee2 *ePtr know about struct employee or am I off basis here?
A more meaningful example might be
struct employee2* manager;
Note that to remove the * means the C compiler must lay out the 44 (or so) bytes needed for the top-level employee, then another 44 bytes for the next inner employee, then the 44 for the next next inner employee, then 44 for the next next next inner employee... and so forth. Needless to say this is a compile error.
Furthermore this impossible structure would force them to all be distinct employees, and would require that when you create any employee you create all the managers, which have to be not null, and distinct. This means you can't have a CEO, whereas with a pointer the CEO's manager could be NULL or herself, depending on your implementation. It also makes it rather impossible to change managers without deleting a record from the employee system (i.e. firing an employee) and recreating it (hiring), which also requires revoking building access, computer access, and so forth. My point in saying this is that to not have a pointer is a really, really bad way to model what's going on in the real world.
However the C compiler can lay out 44 bytes for the employee then 4 for the address of the employee's manager, which will in turn point to 44+4 bytes, if it's not null. Note these aren't necessarily distinct bytes - perhaps an employee is her own manager (your business logic should prohibit this but hey, what does C care).
A lower-level example is a linked list, which goes something more like this:
typedef struct {
int data;
node* next;
} node;
But again, same idea. Unless you have all infinity distinct nodes ready to create at once, this won't work. Linked lists will end in a NULL value, which is possible to express with a pointer, but not a structure that can't be null since it needs to take memory.
Anyway pointers are ways for one structure to refer to another structure without physically laying out the memory again. C is a low level language but if you learn to think from the point of view of the compiler some higher level concepts will make sense. For instance, to delete the * would also mean that an employee "owns" her manager. This doesn't make sense from a real-world perspective and doesn't make sense from a memory management perspective. (Although, there are senses in which parents can own children... this isn't a perfect analogy here.)
The magic here becomes clear when you understand the C concept of an incomplete type.
A struct can only contain completed types, i.e. those that the compiler knows the size of.
When the compiler sees
struct foo {
it knows that there will be a struct with the tag foo; this type (struct foo) is incomplete at this very moment. It becomes complete not until the matching } is seen.
However, and this is the magic, a pointer to an incomplete type is a complete type, because the size of any pointer is known--no matter what type it points to. So after the three tokens above, it is okay to declare a struct member
struct foo *ptr_to_struct_foo;
inside a struct foo and before the matching }.
Another often used incomplete type is void--this type cannot even be completed, which is why C doesn't allow you to declare
void foo;
However, it is perfectly fine to declare pointers to such a type:
void *foo;
But indirecting through a ptr-to-void of course is not allowed. Why? Now you know the answer: because that would yield an incomplete type.
you can not put a whole struct inside of itself because it would be infinitely recursive.
but you can put the address of another instance of a struct inside of a struct; which is what a pointer is... an address the size of SomeStruct* is always the same, so the compiler knows how much memory to make for one instance of the struct.
This would cause the size to be infinite. Think about the struct:
struct my_struct {
int x;
struct my_struct y;
}
This would have a size:
sizeof(struct my_struct) >= sizeof(int) + sizeof(struct my_struct);
Which clearly is not solvable.
However, a pointer to a struct would not have this problem.
struct my_struct2 {
int x;
struct my_struct2* y;
}
As the size is now possible.
sizeof(struct my_struct2) >= sizeof(int) + sizeof(struct my_struct2*);
You should understand the difference between
sizeof(struct my_struct2)
and
sizeof(struct my_struct2*)