1

I am trying to attach an array of strings to the shared memory in C. I have tried my best to attach the array of strings ( array1 and array 2 to the shared memory).

Here, array1 and array2 are arrays of strings of width 20 characters and size 5 ( How do I specify that in the attachment is also not very clear to me). Also, a and b are 1-D integer and float arrays respectively, of size 5.

I want to change the state of the array of strings by updating their value at runtime, as I am doing.

#include <stdio.h>
#include <stdlib.h>
#include<sys/shm.h>
#define NUMBER_OF_DATA  5
int main()
{
   int size=(NUMBER_OF_DATA*(sizeof(int)+sizeof(float))) + (2*(20*NUMBER_OF_DATA));
   key_t key;
   key=ftok("/home/android/Desktop/newww.c",4);
   int shmid=shmget(key,size,0777|IPC_CREAT);

   int *a=(int *)shmat(shmid,0,0);
   float *b=(float *)(a+NUMBER_OF_DATA);
   char **array1=(char **)(b+NUMBER_OF_DATA);
   char **array2=(char **)(array1+(20*NUMBER_OF_DATA));
   int i;
   for(i=0;i<5;i++)
   {
       printf("enter value\n");
       scanf("%s",array1[i]);
   }
   shmdt(&shmid);
   shmctl(shmid,IPC_RMID,0);
   return 0;
}

My other process does the following

int shmid=shmget(key,size,0777|IPC_CREAT);


 int *a1=(int *)shmat(shmid,0,0);
  float *b1=(float *)(a1+NUMBER_OF_DATA);
  char **array11=(char **)(b1+NUMBER_OF_DATA);
  char **array22=(char **)((char *)array11+(20*NUMBER_OF_DATA));
  for(i=0;i<NUMBER_OF_DATA;i++)
    {
      a1[i]=aaa[i];
      b1[i]=bbb[i];
      array11[i]=array111[i];
      array22[i]=array2222[i];
    }

where aaa,bbb,array111 and array222 are other arrays from which the values are loaded into the shared memory by this process. These 2 processes are together not helping me achieve what i wanted.

It would be great if someone could point out the reason and tell me the correct way to attach the array of strings to memory. Thanks.

3
  • 1
    If you use a data structure to represent your buffer layout instead of manually calculating sizes and pointer offsets, you will avoid a large number of problems. Commented Jan 25, 2013 at 18:47
  • You dont need to test the return of schmget and shmat? And that you enter max 19 char in scanf? Where is the error (debugging)? Commented Jan 25, 2013 at 18:49
  • Also see the answers to this related question Commented Jan 26, 2013 at 19:42

1 Answer 1

5

Let’s use a debugger to find where the error is happening. First compile with debugging turned on, then run it:

$ gcc -g foo.c -o foo
$ gdb foo

GNU gdb 6.3.50-20050815 (Apple version gdb-1822) (Sun Aug  5 03:00:42 UTC 2012)
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "x86_64-apple-darwin"...Reading symbols for shared libraries .. done

(gdb) run
Starting program: foo 
Reading symbols for shared libraries +............................. done
enter value
12

Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_INVALID_ADDRESS at address: 0x0000000000000000
0x00007fff928d3143 in __svfscanf_l ()

The bt command, short for backtrace, will show where the error occurred:

(gdb) bt
#0  0x00007fff928d3143 in __svfscanf_l ()
#1  0x00007fff928d0f6f in scanf ()
#2  0x0000000100000e6b in main () at foo.c:20

Here it’s line 20, calling scanf(). Let’s move up the stack to get into the right frame:

(gdb) up
#1  0x00007fff928d0f6f in scanf ()
(gdb) up
#2  0x0000000100000e6b in main () at foo.c:20
20         scanf("%s",array1[i]);

And now the p command, short for print, to examine values.

(gdb) p array1
$1 = (char **) 0x100034028
(gdb) p i
$2 = 0
(gdb) p array1[i]
$3 = 0x0

Aha! The line scanf("%s", array1[i]) is trying to store a string to the value of array1[i]—0—rather than to its address.

Let’s fix that by changing the line to:

   scanf("%s", &array1[i]);

Now, recompile, and it works:

$ ./foo
enter value
12
enter value
14
enter value
15
enter value
17
enter value
19

However, there’s now a compiler warning on my machine:

foo.c: In function ‘main’:
foo.c:20: warning: format ‘%s’ expects type ‘char *’, but argument 2 has type ‘char **’
foo.c:20: warning: format ‘%s’ expects type ‘char *’, but argument 2 has type ‘char **’

But that’s another question for you to figure out :)

Sign up to request clarification or add additional context in comments.

5 Comments

This program now works fine but now I get a segmentation fault on the other process sharing the memory as soon as i enter a value
@andrew....in the other process when I print array1[i] after entering a string here, it prints correctly, but the initial values are some garbage ascii character...is the warning creating the problem? How do i remove the warning?
Can you try applying the same technique used in this answer to the other program? Run it under a debugger to find where the segfault is occurring, and use the debugger’s p command to examine variable values and make sure they are what you expect them to be.
I seek your help. The other process runs fyn. But this process is not able to change the content of shared data loaded into the shared memory by the other process. Check my edit for the other proces
In the debugger, set a breakpoint just before you detach call shmdt() by typing break foo.c:20 in gdb before you run. Start with the simplest thing IPC program possible—writing a single character into shared memory from one process and reading it from another. Then get that working with passing a pointer to a character instead of a single character, and gradually work your way up to passing an array of strings. Use the debugger throughout to make sure it’s doing exactly what you expect.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.