1

In a C program , i create a shared memory segment of large size and then put a variable number of structs into it (2 in this example).

strcut message * x;
x = (struct message *)shmat(shmid,NULL,0);
x[0].a = 1;
x[0].b = 2;
x[1].a = 3;
x[1].b = 4;

There is a reader program which has to read all the structs written in the shared memory segment but does not know how many structs are there. I have tried the following way:

struct message * x;
x = (struct message *)shmat(shmid,NULL,0);
 while(x!=NULL)
 {
printf("x.a = %d\n",x->a);
printf("x.b = %d\n",x->b);
printf("\n\n");
x=x++;
}

It gives me the 2 structs correctly but after that it gives me 0 (or random garbage values ) for many more times ( for both a and b ) until it runs out of the shared memory segment and then gives a segmentation fault. How do i go about it?

I am using UBUNTU.

jps
  • 173
  • 1
  • 13

1 Answers1

2

You are checking for while(x != NULL) -- it never be NULL if shmat() returned non-NULL value (unless you will count with pointer overflow, but you will get SEGV early).

If you want to keep bunch of structs in memory, save their number too and reuse on consumer side.

I.e. producer:

char* ptr = shmat(shmid,NULL,0);

if(ptr != ((char*) -1)) {
    uint32_t* p_msg_count = (uint32_t*) ptr; 
    struct message* x = (struct message*) (ptr + sizeof(uint32_t));

    *p_msg_count = 2;  // <------

    // Fill in x
}

Consumer:

char* ptr = shmat(shmid,NULL,0);
int xid, xcount;

if(ptr != ((char*) -1)) {
    uint32_t* p_msg_count = (uint32_t*) ptr; 
    struct message* x = (struct message*) (ptr + sizeof(uint32_t));

    xcount = (int) *p_msg_count; 
    for(xid = 0; xid < xcount; ++xid) {
        // Print x[xid] 
    }
}

P.S. x = x++; -- this is also very bad (I think that even compiler should complain here). If you want to get "next" x, use prefix increment alone: ++x

myaut
  • 11,174
  • 2
  • 30
  • 62
  • Thanx @myaut, it helped. I did not get the problem in doing x++. Can you elaborate a bit ? – jps Apr 03 '15 at 12:19
  • 1
    @jps, C forbids modifying variable within statement more than once because it is undefined in which order modifications should apply. In your case it is assigned `x =` and incremented `x++`. Postfix increment should return current value of `x`, so there is a chance that your code will be compiled into that: `tmp = x; ++x; x = tmp;` and `x` never being incremented. Probably you mean `x = x + 1` which is correct? – myaut Apr 03 '15 at 12:27
  • Here is an example of such confusion: [Index, assignment and increment in one statement behaves differently in C++ and C#. Why?](http://stackoverflow.com/questions/1606407/index-assignment-and-increment-in-one-statement-behaves-differently-in-c-and) – myaut Apr 03 '15 at 12:29