1

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

这里,array1 和 array2 是宽度为 20 个字符和大小为 5 的字符串数组(我如何在附件中指定它对我来说也不是很清楚)。此外,a 和 b 分别是一维整数和浮点数组,大小为 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 是其他数组,此进程从中将值加载到共享内存中。这两个过程加在一起并不能帮助我实现我想要的。

如果有人能指出原因并告诉我将字符串数组附加到内存的正确方法,那就太好了。谢谢。

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

bt命令是 backtrace 的缩写,将显示错误发生的位置:

(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

啊哈!该行scanf("%s", array1[i])试图将字符串存储到值—0array1[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 回答