将字符串数组附加到共享内存 - 分段错误

时间:2013-01-25 18:26:48

标签: c arrays shared-memory

我正在尝试将一个字符串数组附加到C中的共享内存中。我已尽力将字符串数组(array1和array 2)附加到共享内存中。

这里,array1和array2是宽度为20个字符且大小为5的字符串数组(如何指定附件中的字符串对我来说也不是很清楚)。 此外,a和b分别是1-D整数和浮点数组,大小为5。

我想通过在运行时更新它们的值来改变字符串数组的状态,就像我一样。

#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是其他数组,通过此过程从中将值加载到共享内存中。 这两个过程无法帮助我实现我想要的目标。

如果有人能够指出原因并告诉我将字符串数组附加到内存的正确方法,那将会很棒。感谢。

1 个答案:

答案 0 :(得分: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 ()

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命令(打印的缩写)来检查值。

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

啊哈!第scanf("%s", array1[i])行正在尝试将字符串存储到array1[i] - 0的,而不是地址

让我们通过将行更改为:

来解决这个问题
   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 **’

但这是你要弄明白的另一个问题:)