2015-01-03 40 views
0

我的任务是使用程序创建共享内存。它将字符串从命令行参数写入共享内存部分。它会被另一个程序读取。我正在使用结构来创建共享内存。现在,我的问题是我无法将命令行中给出的字符串传递给结构变量。如何将多个字符串写入一个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; 
}; 
+0

你可能笏使用某种共享的信号或自旋锁,而不是简单的“INT状态”它有助于避免竞争条件和可能比检查更efficint休眠循环。 – Jasen

回答

1

,你必须将蜇复制到共享内存中的缓冲区,因为共享内存可以有不同的基础地址在每个进程中,你将不得不引用它们通过偏移到缓冲区而不是通过指针。

然后,您还必须在缓冲区中保留已用/免费的地图,以便知道哪些部分是空闲的以及使用哪些部分。共享内存有利于广播数据,但是在两个进程之间,通常更容易使用某种套接字(unix或inet)或管道(匿名或命名)。

0

主要问题是,你的结构只包含字符串指针,而不是实际的字符串内容(仍位于内存中属于原工艺,共享内存)的事实。

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

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

您已经使用strcpy将数据复制到结构,所以它没有太多的代码修改工作。虽然我强烈建议您用不易于出现buffer overflow的东西替换strcpy。缺点:如果字符串长度不同,那么由于数组的固定大小,您的结构可能会包含大量未使用的空间。另一种方法是使用单个一维字符数组并简单地连接十个字符串,使用\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; 
} 

当然,你将不得不作出在接收端类似的变化;在每个'\ 0'字符处分割数据。


有点偏离主题,这段代码是错误的:

所有的
while(dataptr != TAKEN); 
sleep(1); 

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

我想你想做到这一点:

while (dataptr->status != TAKEN) 
    sleep(1); 
相关问题