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

标签 c arrays shared-memory

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

这里,array1和array2是宽度为20个字符,大小为5的字符串数组(我在附件中如何指定我也不是很清楚)。 此外,a 和 b 分别是大小为 5 的一维整数和 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 个过程并没有帮助我实现我想要的。

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

最佳答案

让我们使用调试器找出错误发生的位置。首先在打开调试的情况下编译,然后运行它:

$ 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()。让我们向上移动堆栈以进入正确的帧:

(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]) 行试图将字符串存储到 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 **’

但那是你要弄清楚的另一个问题:)

关于c - 将字符串数组附加到共享内存 - 段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14528080/

相关文章:

c - C链表中的内存泄漏

更改位数组中的值

ASP.NET MVC : Use byte array as source of IMG tag through ViewData?

c - int *array[32] 是指向 32 个 int 数组的指针,还是指向 int 的 32 个指针数组?有关系吗?

python - 如何在线程之间共享对象?

c - 除了共享内存的大小之外,是什么阻止了我进一步读/写? (系统 V IPC)

c - 如何在其他函数中使用二维数组?不知道如何让它发挥作用

c - 与打印文本和 NL 相比,先打印 NL,然后打印文本,然后手动刷新的任何原因?

c - 内存并在共享内存中的指针中传递值

c - 如何从 C 中的 mmap 区域获取固定大小的缓冲区?