Question about struct in shared memory (C on linux) - Unix

This is a discussion on Question about struct in shared memory (C on linux) - Unix ; 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 ...

+ Reply to Thread
Results 1 to 6 of 6

Thread: Question about struct in shared memory (C on linux)

  1. Question about struct in shared memory (C on linux)

    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.

  2. Re: Question about struct in shared memory (C on linux)


    > 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

  3. Re: Question about struct in shared memory (C on linux)

    hugo.arregui@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@toerring.de
    \__________________________ http://toerring.de

  4. Re: Question about struct in shared memory (C on linux)

    hugo.arregui@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.

  5. Re: Question about struct in shared memory (C on linux)

    On Jul 3, 11:53*am, "hugo.arre...@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

  6. Re: Question about struct in shared memory (C on linux)

    David Schwartz wrote:
    > On Jul 3, 11:53 am, "hugo.arre...@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.
    >

    Unless the page is mapped to the same address in each process.

    --
    Ian Collins.

+ Reply to Thread