Reputation: 183
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.
Upvotes: 1
Views: 316
Reputation: 11504
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
Upvotes: 2