From: hugo.arregui on
Hi!

I have two struts like that:

struct {
int num;
int num2;
struct b arrayOfB[SIZE];

} a;

struct {
int num3;
int num4

} b;

I put struct a into Shared Memory:
shmid = shmget(IPC_PRIVATE, sizeof(struct b), 0666)

and atach it in two process:
ptr = shmat(shmid, 0, 0);

This works fine, but now i must delete the constant SIZE:

I will obtain the SIZE in runtime, before execute the shmget function.

the new struct a:

struct {
int num;
int num2;
struct b *arrayOfB;

} a;

now:

I put struct a into Shared Memory:
shmid = shmget(IPC_PRIVATE, sizeof(struct a) + sizeof(struct b) *
size, 0666);

and atach it in two process:
ptr = shmat(shmid, 0, 0);

my question is: how can tell arrayOfB to point over the shared memory?

i thought:

struct a *ptr,p2*;
p2 = ptr; //ptr is the shmat return
p2++;
ptr->arrayOfB

but doesn't work. in another way i read about the shmat parametrs, but
don't understand how (if its possible) use to solve my trouble.

Thanks.
From: ppi on

> the new struct a:
>
> struct {
> int num;
> int num2;
> struct b *arrayOfB;
>
> } a;
>
> now:
>
> I put struct a into Shared Memory:
> shmid = shmget(IPC_PRIVATE, sizeof(struct a) + sizeof(struct b) *
> size, 0666);
>
> and atach it in two process:
> ptr = shmat(shmid, 0, 0);
>
> my question is: how can tell arrayOfB to point over the shared memory?

you cannot do that: for each process thw shared memory will be mapped
to a different address, hence storing pointers values inside the
shared memory segment is useless: 0x12345678 for process A, and
0x87654321 for process B.

>
> but doesn't work. in another way i read about the shmat parametrs, but
> don't understand how (if its possible) use to solve my trouble.

You can try to use something like the mesg V queues trick i.e.

struct {
int num;
int num2;
struct b arrayOfB[1];
} a;

shmid = shmget(IPC_PRIVATE, sizeof(struct a) + sizeof(struct b) *
(size - 1), 0666);

I do not remember if there is a padding/alignment issue there though.
Maybe another poster could clarify that ?

cheers,
-- paulo
From: Jens Thoms Toerring on
hugo.arregui(a)gmail.com <hugo.arregui(a)gmail.com> wrote:
> Hi!

> I have two struts like that:

> struct {
> int num;
> int num2;
> struct b arrayOfB[SIZE];
> } a;

I guess you mean

struct a {
int num;
int num2;
struct b arrayOfB[SIZE];
};

and

> struct {
> int num3;
> int num4
> } b;

struct b {
int num3;
int num4
};

(and b must come before a if you want to create an array of b's
in a).

> I put struct a into Shared Memory:
> shmid = shmget(IPC_PRIVATE, sizeof(struct b), 0666)

> and atach it in two process:
> ptr = shmat(shmid, 0, 0);

> This works fine, but now i must delete the constant SIZE:

> I will obtain the SIZE in runtime, before execute the shmget function.

> the new struct a:

> struct {
> int num;
> int num2;
> struct b *arrayOfB;
> } a;

Again, make that

struct a {
int num;
int num2;
struct b *arrayOfB;
};

> now:

> I put struct a into Shared Memory:
> shmid = shmget(IPC_PRIVATE, sizeof(struct a) + sizeof(struct b) *
> size, 0666);

Don't you also need IPC_CREATE to creates the shared memory area?

> and atach it in two process:
> ptr = shmat(shmid, 0, 0);

> my question is: how can tell arrayOfB to point over the shared memory?

Use

ptr->arrayOfB = ( struct B * ) ( ( char * ) a + sizeof( struct a ) );

But your approach is a bit dangerous since there are some potential
lignment issues (is a pointer pointing directly after 'struct a'
suitable aligned to point to a 'struct b'?) that could get in the
way. So I would recommend to create two shared memory areas, one
for 'struc a' and one for the arrays of 'struct b'. Create shared
memory with

shmid1 = shmget( IPC_PRIVATE, sizeof( struct a ),
IPC_CREAT | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP );
shmid2 = shmget( IPC_PRIVATE, size * sizeof( struct b ),
IPC_CREAT | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP );

and then do

struct a * ptr = shmat( shmid1, NULL, 0 );
ptr->arrayOfB = shmat( shmid2, NULL, 0 );

Regards, Jens
--
\ Jens Thoms Toerring ___ jt(a)toerring.de
\__________________________ http://toerring.de
From: Phil on
hugo.arregui(a)gmail.com wrote:
> Hi!
>
> I have two struts like that:
>
> struct {
> int num;
> int num2;
> struct b arrayOfB[SIZE];
>
> } a;
>
> struct {
> int num3;
> int num4
>
> } b;
>
> I put struct a into Shared Memory:
> shmid = shmget(IPC_PRIVATE, sizeof(struct b), 0666)
>
> and atach it in two process:
> ptr = shmat(shmid, 0, 0);
>
> This works fine, but now i must delete the constant SIZE:
>
> I will obtain the SIZE in runtime, before execute the shmget function.

You have two basic choices:

Either declare "struct b arrayOfB[min]" (where min is maybe 1) and then
allocate enough space for all the elements, as other posters have
suggested. This is probably the simplest method.

Or, implement some sort of allocator to share out blocks of memory in
the shared region, and then store offsets in place of pointers. i.e.

typedef intptr_t offset_t;
void* get_ptr(offset_t offset) { return start_of_shmem + offset; }
offset_t allocate(size_t sz) .....
void deallocate(offset_t o) .....

struct a {
....
offset_t ofs_to_b;
};

struct a A;
A.ofs_to_b = allocate(SIZE * sizeof(b));

etc. etc. This gives you the full flexibility that you would get from
pointers but with some complexity, as you can see.

Note that if you store pointers in the shared memory your program will
probably work perfectly. For several weeks. But then it will break, as
soon as you demonstrate it to your boss, because the shared memory will
get different addresses in the different processes.


Phil.
From: David Schwartz on
On Jul 3, 11:53 am, "hugo.arre...(a)gmail.com" <hugo.arre...(a)gmail.com>
wrote:

> but doesn't work. in another way i read about the shmat parametrs, but
> don't understand how (if its possible) use to solve my trouble.

A pointer in or to shared memory is useless, because there is nothing
useful another process can do with it. You have a few choices, but the
most flexible is to use an offset from the base of the shared memory
area instead of a pointer.

DS