如何使用指针数组将多个字符串存储到结构中

时间:2015-01-03 19:41:30

标签: c shared-memory

我的任务是使用程序创建共享内存。它将字符串从命令行参数写入共享内存部分。然后由另一个程序读取。我正在使用结构来创建共享内存。现在,我的问题是我无法将命令行中给出的字符串传递给结构变量。如何将多个字符串写入char变量的一个指针数组?

#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <malloc.h>
#include "shm-com.h"

void main(int argc,char *argv[])
{
 key_t shmKey;
 int shm_id,i,j=0;
 struct memory *dataptr;
 char *string[10];

 shmKey = ftok(".",1234);
 printf("no. of strings %d\n",argc);

 shm_id  = shmget(shmKey,sizeof(struct memory),0666 | IPC_CREAT);

 if(shm_id < 0)
 {
  perror("shm_id didn't create\n");
  exit(0);
 }

 dataptr = (struct memory *)shmat(shm_id,NULL,0);
 if((int) dataptr == -1)
 {
  perror("****didn't attatch to share memory\n");
 }

 printf("share memory attatched at %p address\n",dataptr);

 dataptr->status = NOT_READY;
 for(i = 1;i < argc;i++)
 {
 string[j] = argv[i];
 j++;
 }
 printf("data attached to share memory\n");

 for(i = 0;i < argc ; i++)
 {
 printf("%s\n",string[i]);
 }

 for(i = 0;i < argc;i++)
 {
 strcpy(dataptr->data[i],argv[i]);

 }

 dataptr->status = FILLED;

 printf("please start client window\n");

 while(dataptr != TAKEN);
 sleep(1);

 shmdt((void *)dataptr);
 printf("server has detached sharre memory\n");

 shmctl(shm_id,IPC_RMID,NULL);

 printf("server cancelled shared memroy\n");
 exit(0);
 }

我的结构文件名shm-com.h是

#define TAKEN 1
#define FILLED 0
#define NOT_READY -1

struct memory
{
 char *data[10];
 int status;
};

2 个答案:

答案 0 :(得分:1)

你必须将stings复制到共享内存中的缓冲区中,并且因为共享内存在每个进程上可能有不同的基址,所以你必须通过offset将它们引用到缓冲区而不是指针。

然后,您还必须在缓冲区中维护一个已用/自由的地图,以便了解哪些部分是免费的以及哪些部分是免费使用的。

共享内存适用于广播数据,但在两个进程之间通常更容易使用某种套接字,(unix或inet)或管道(匿名或命名)。

答案 1 :(得分:0)

主要问题是你的struct只包含字符串指针,而不是实际的字符串 content (它仍然位于属于原始进程的内存中,< em> not 在共享内存中。)

最简单的解决方案是使用二维字符数组。

struct memory
{
    char data[10][100];
    int status;
};

您已经使用strcpy将数据复制到结构中,因此无需更改代码即可运行。虽然我强烈建议您将strcpy替换为不容易buffer overflow的内容。

缺点:如果字符串长度不同,那么由于数组的大小固定,您的结构可能包含大量未使用的空间。另一种方法是使用单个一维字符数组,并使用\0作为分隔符简单地连接十个字符串。

部分代码(只是更改):

struct memory
{
    int status;
    char data[1];     /* data MUST be last in the struct! */
};

int size = sizeof(struct memory) - 1;   /* subtract one because [1] will be overruled */
for (i = 1; i < argc; i++)
{
    size += strlen(argv[i]) + 1;        /* adding one to hold '\0' */
}

shm_id  = shmget(shmKey, size, 0666 | IPC_CREAT);   /* I adjusted the size parameter here */

int offset = 0;
for (i = 1; i < argc; i++)
{
    strcpy(dataptr->data + offset, argv[i]);
    offset += strlen(argv[i]) + 1;
}

当然,您必须在接收端进行类似的更改;在每个&#39; \ 0&#39;分割数据字符。


有点偏离主题,这段代码错了:

while(dataptr != TAKEN);
sleep(1);

首先,您要将指针与整数进行比较(请启用编译器警告)。就像现在一样,它是一个无限循环。即使它不是,它也是一个CPU密集型busy-waiting循环。如果sleep(1);应该是循环的一部分(肯定会给CPU一些休息),那么你应该删除while语句末尾的分号。

我想你想这样做:

while (dataptr->status != TAKEN)
    sleep(1);