PDA

View Full Version : Dynamic Array In Shared Memory


guepard53
05-25-2004, 08:36 AM
Hello !

In C, I want to put a dynamic array (*tab for example) in shared memory (shmget, shmat). It works but when the size of the array begins to grow, the writing in the array doesn't work... Can I make a 'malloc' of a dynamic array stored in shared memory ? Or something like that... (the size of the shared memory is big enough to work...)

Tanks (English's not my motherlanguage... :roll: )

Nope
05-25-2004, 03:10 PM
So you created a shared memory segment with shmget and attached it properly. Assuming that you've set your mode flags right in the shmget you should then be able to read/write within its boundaries without problems.

So if the size is 1000*sizeof(int) and tab is a pointer to int

int *tab;
tab=(int*)shmat(shared_mem_id,0,0);

then you can access tab[0] to tab[999]. If it is now getting bigger than that you have to create a new segment with the new size, attach it, copy the values over and then destroy the old one.

guepard53
05-26-2004, 07:30 AM
Thanks for your answer first !

Your solution works if my array is a defined type (int, char, ...) but my array is an array of structures (made by myself) like :

struct myStruct { char text[100000]; unsigned long int size; };

So, I define a shared memory segment with

shmid = shmget( cle, 1000*sizeof(struct myStruct, IPC_CREAT | 0666);

(cle is defined with ftok.)

After that :

myStructArray = shmat(shmid,0,0);

(struct myStruct *myStructArray is defined before of course)

If I want to put something in myStructArray[100].text for example, I have a segmentation fault...

What's my error ?

i3839
05-26-2004, 10:14 AM
I assume that you made a typo and in your actual code it's correct. If not, then you forgot a closing ).

shmid = shmget( cle, 1000*sizeof(struct myStruct), IPC_CREAT | 0666);

guepard53
05-26-2004, 10:17 AM
Yes, it's a typo fault, in my code it's correct (If not, I should have a error in compilation) :roll:

RobSeace
05-26-2004, 11:38 AM
Does your machine have enough free memory to handle as much
as you're allocating there? It's quite a lot; roughly 100MB, it looks
like... And, even if you have the free RAM, some systems will only
set aside a part of it for use as shared memory, too... So, maybe
you're simply exceeding the limits of available memory... (And, as
for why the initial allocation didn't fail, perhaps for the same reason
that on many systems a malloc() of an insanely huge amount won't
fail, but later trying to actually access all of it will seg-fault in the
same way... Namely, some systems overcommit memory, in the
hope that you won't really need to use as much as you asked for,
so only try to actually give it all to you later, when you try to really
use it; at which point, they THEN can fail, if they're unable to give
it all to you...)

Or, it could be something completely different... I don't know...

Nope
05-26-2004, 12:05 PM
The real problem is most likely that you don't get the shared memory in
the first place and just skip the error check. My system wouldn't give me
1000 of your "mystruct" either. So you tried to write at the address -1 and
that will cause a segfault...

Always check for errors if you create a resource to prevent running into
such things.

You try to get 100004Bytes*1000=100004000 Bytes or ~100MByte. Most
likely that your shared mem won't give you that. If you really need such a
big shared memory area, use a file together with mmap, that should work
and in the end it'll be almost as fast. Several programs using mmap on the
same file share the mmaped memory area unless you specify otherwise,
and you can use spin locks to organise the access...