1

文字列の配列をCの共有メモリに接続しようとしています。文字列の配列(配列1と配列2)を共有メモリに接続するために最善を尽くしました。

ここで、array1とarray2は、幅20文字とサイズ5の文字列の配列です(添付ファイルでそれを指定する方法も、私にはあまり明確ではありません)。また、aとbは、それぞれサイズ5の1-D整数配列とfloat配列です。

私が行っているように、実行時に値を更新することにより、文字列の配列の状態を変更したいと思います。

#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;
}

私の他のプロセスは次のことを行います

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];
    }

ここで、aaa、bbb、array111、およびarray222は、このプロセスによって値が共有メモリにロードされる他の配列です。これらの2つのプロセスは一緒になって、私が望んでいたことを達成するのに役立っていません。

誰かが理由を指摘し、文字列の配列をメモリにアタッチする正しい方法を教えてくれれば素晴らしいと思います。ありがとう。

4

1 に答える 1

5

デバッガーを使用して、エラーが発生している場所を見つけましょう。最初にデバッグをオンにしてコンパイルし、次に実行します。

$ 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 ()

backtraceのbt略であるコマンドは、エラーが発生した場所を示します。

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

これが20行目scanf()です。upスタックを移動して、適切なフレームに入りましょう。

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

そして今、p値を調べるための、printの略であるコマンド。

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

あはは!この行は、文字列をアドレスではなく、-0にscanf("%s", array1[i])格納しようとしています。array1[i]

行を次のように変更して修正しましょう。

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

ここで、再コンパイルすると、機能します。

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

ただし、私のマシンにはコンパイラの警告が表示されます。

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 **’

しかし、それはあなたが理解するための別の質問です:)

于 2013-01-25T18:45:10.527 に答える