将字符串存储在 mmap 共享数组中? (C)

Posted

技术标签:

【中文标题】将字符串存储在 mmap 共享数组中? (C)【英文标题】:storing strings in a mmap shared array? (C) 【发布时间】:2018-02-14 21:37:23 【问题描述】:

我正在尝试使用 mmap 将当前目录中的所有文件名存储在共享数组中,我可以将目录中的所有 9 个文件打印到屏幕上,但是当我尝试将它们存储在数组 (shared_array) 中并打印数组时,所有条目都包含相同的字符串 (file.txt)。提前致谢!

char **shared_array; 
shared_array= mmap(0,100*sizeof(char*),PROT_READ | PROT_WRITE,MAP_SHARED | MAP_ANON,-1,0);  
char * filename;

const MAXLINE = 80; 
char line [MAXLINE];

FILE *fp = popen("/bin/ls","r");

int i = 0; 
while(fgets(line, MAXLINE,fp) !=NULL)    
    filename = line;
    shared_array[i] = filename; 
    i++;        

pclose(fp);

int j;
for(j=0;j<i;j++)
    printf("\n%s",shared_array[j]);

【问题讨论】:

共享内存中的指针通常没有用处,因为它们指向的地址是特定于进程的。 【参考方案1】:

当你这样做时:

filename = line;
shared_array[i] = filename; 

您实际上并未将line 数组的内容复制到shared_array。您将line 的地址分配给每个数组元素。结果,所有数组元素都指向同一个地方,即line,它将只包含最近存储的值。

您需要为要复制的每个字符串分配内存。你可以用strdup做到这一点:

shared_array[i] = strdup(line);

但是这样做的问题是您的共享内存包含指向非共享内存的指针。

您需要在共享内存中为字符串数组分配空间:

const MAXLINE = 80;
char (*shared_array)[MAXLINE]; 
shared_array= mmap(0,100*MAXLINE,PROT_READ | PROT_WRITE,MAP_SHARED | MAP_ANON,-1,0);

然后你可以使用strcpy复制到每个数组元素中:

strcpy(shared_array[i], line); 

【讨论】:

如果指针指向非共享地址,那么将指针放入共享内存有什么意义? 但是请注意,使用 strdup 分配的内存将不是共享内存(这似乎是原始问题的重点)。要获得原始发布者想要的内容,需要将字符串打包到共享内存中。【参考方案2】:

如果 MAXLINE 表示每个大小为 N 的字符串的总数:-

你不能这样做。它会给出一个非常长的字符串,大小为 MAXLINE X N,并且必须使用偏移量来访问子字符串。

char (*shared_memory)[MAXLINE]  -> returns pointer to a string of size MAXLINE.
shared_array= mmap(0,100*MAXLINE,PROT_READ | PROT_WRITE,MAP_SHARED | MAP_ANON,-1,0);

你需要这样做

char *shared_memory[MAXLINE] - This returns array of char pointers

for(int i=0; i<MAXLINE;i++)
shared_memory[i] = mmap(NULL,sizeof(char)*N,PROT_READ | PROT_WRITE,MAP_SHARED | MAP_ANONYMOUS,-1,0);

现在你可以通过 shared_memory[i] 访问字符串。 即使每个字符串都小于页面粒度,您也会浪费空间,但访问起来会更容易。

或者干脆使用

char shared_memory[100][MAXLINE];

【讨论】:

以上是关于将字符串存储在 mmap 共享数组中? (C)的主要内容,如果未能解决你的问题,请参考以下文章

C内存共享进程通信范例

如何在 Ada 中使用 Linux 将任意字符串写入并读取到共享内存?

如何将字符串数组附加到共享内存? C

mmap()共享内存详解

如何将Unicode字符存储在数组中?

linux共享内存和mmap的区别