1

I have a data structure that acts as a buffer. It's two structures that have a char *color within them. I am able to store and retrieve the correct color out of each producer process by themselves, but the consumer does not seem to see anything in the color variable, though it knows it's not null. How can this be?

typedef struct {
    char *color;
    struct timeval time; 
} data_struct;

typedef struct{
    data_struct buf1;
    data_struct buf2;
} buffer;

In the producer I store:

        ptr->buf1.color = color;
        gettimeofday (&tval, NULL);
        ptr->buf1.time = tval;

And I am able to then print the color it just stored and it does work within the same process. But the consumer uses:

printf("%s\t", ptr->buf1.color);
struct timeval tval = ptr->buf1.time;
printf("%ld\n", (tval.tv_sec)*1000000L + tval.tv_usec);

And he just ends up printing a blank area, then a tab, then the time in seconds. How is it accessing the same shared memory but not seeing my string?? This approximately identical code works in the threaded version just fine. Thanks for your help!

Update with shared memory segments.

    int shmem_id;
    buffer *shmem_ptr;
    key_t key = 7484;
    int size = 2048; 
    int flag = 1023;

    char keystr[10];

    /* create a shared memory segment */
    shmem_id = shmget (key, size, flag);    
    shmem_ptr = shmat (shmem_id, (void *) NULL, 1023);
    shmem_ptr->buf1.color = NULL;
    shmem_ptr->buf2.color = NULL;
    sprintf (keystr, "%d", key);
nicholas.reichel
  • 2,260
  • 7
  • 20
  • 28
  • What is the datatype of color in: ptr->buf1.color = color; ? – afic Oct 30 '14 at 02:18
  • Color is char *color; and later color = "RED"; I was able to solve it using strcpy and char color[8] in the struct instead of using pointers, but am wondering if this is the only way. I found the solution here: http://stackoverflow.com/questions/15534923/assigning-strings-in-shared-memory-processes It is interesting though that these problems did not occur with threads. – nicholas.reichel Oct 30 '14 at 02:26
  • Two possibilities come to mind: (1) are you placing the data in the shared memory segment or are you mallocing it? (2) Are both processes mapping the shared segment to the same virtual address? If not on the second, the pointer, as seen by the consumer, will be pointing to the wrong place. If this isn't clear, I'd suggest showing us the code for mapping the shared memory and for allocating the buffers. – DoxyLover Oct 30 '14 at 02:32

3 Answers3

1

Even though buf may be in shared memory, that does not guarantee that color is also pointing to something in shared memory. My guess is that color is pointing at some address that is only visible to the producer process and not the consumer process. To fix this, you could define the color field as a fixed length char array, and use

strncpy(ptr->buf1.color, color, BUFLEN);
ptr->buf1.color[BUFLEN-1] = '\0';

to set the color.

JS1
  • 4,745
  • 1
  • 14
  • 19
0

I think the reason that you are not malloc the struct and buffer properly as they are not protected and thus it would be over written by any thing. Try to do things like these:

 typedef struct {
   char *color;
    struct timeval time; 
} data_struct;


data_struct *temp=(data_struct*)malloc(sizeof(data_struct));

temp->color = (char *)malloc(strlen(color)+1);

strcpy(temp->color, color);

I think doing these would not generate problem. But remember to free the allocated memory first of string then structure.

  free(temp->color);
  free(temp);
Vineet1982
  • 7,730
  • 4
  • 32
  • 67
0

It doesn't work because you have one process which stores a pointer, and a separate process which reads that pointer. But these two processes do not share the same address space, so the pointer is meaningless when read. You could solve this a few ways:

  1. Use threads instead of processes; this way the producer and consumer will have a single address space and pointers from one will be valid in the other.
  2. Store the text directly in the struct, without a pointer indirection (i.e. char color[30]).
  3. Store an "offset pointer" in the struct, and store the character data somewhere else in the shared memory region (a sort of pool allocator).
  4. Make an array of fixed strings in the producer and consumer and just store the index into that lookup table. This works if the strings are known in advance.
John Zwinck
  • 239,568
  • 38
  • 324
  • 436