在一个mmap共享数组中存储字符串?(C语言)

3

我正在尝试使用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
共享内存中的指针通常没有用,因为它们所指向的地址是进程特定的。 - Barmar
2个回答

4
当你执行以下操作时:
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); 

1
如果指针指向非共享地址,将指针放入共享内存的意义何在? - Barmar
请注意,使用strdup分配的内存不是共享内存(这似乎是原问题的关键)。要实现原始帖子作者想要的内容,需要将字符串打包到共享内存中。 - wjl

1

如果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];

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接