在共享内存进程中分配字符串

5

我有一个程序需要在两个进程之间共享一个字符串。我已经声明了一个包含*char数组的结构体。在主进程被fork之前,使用shmgetshmat分配了这个结构体。

typedef struct Queue
{
    int index;
    char *directory[10];
} Queue;

在其中的一个过程中,我尝试设置值:data->dir_name是一个*char类型指针,将其设置为类似于"/data1"的字符串。
queue->directory[i] = data->dir_name; // Option 1
queue->directory[i] = "foo";          // Option 2

我的问题是,上面的第一条和第二条语句有什么区别?当将queue->directory[i]设置为"foo"时,其他进程可以看到它。然而,传递值data->dir_name时却不行。
提前感谢!

你确定它们没有声明或在程序的不同位置设置吗?我唯一能想到的情况是一个进程在另一个进程将数据写入文件之前读取了该数据。 - tay10r
1
也许你在使用 queue->directory[i] 之前的某个地方调用了 free(data->dir_name)?此外,data->dir_name 可能是一个自动变量。 - Eddy_Em
1
你能分享更多的代码吗?在哪里进行了进程分叉? - tay10r
它们设置在程序的相同部分。我在源代码中将“code”(data->dir_name)更改为“code”“foo”,然后重新编译它,并看到“foo”出现了,但data->dir_name的值并没有改变。 - burtmacklin16
1个回答

5
问题在于你只是赋予了一个指针,而没有复制字符串数据。第一种情况下,你正在将值设置为指向第二个进程无法看到的内存。当你执行第一行时,指针 data -> dir_name 被放置在queue->directory[i]中,但当另一个进程查看其自己内存空间中的该内存地址时,数据并不存在那里。另一方面,第二行将静态字符串"foo" 的地址放入变量中。由于这些进程是从相同的源代码编译而来,所以该字符串在每个进程的内存中都是相同的位置,因此第二个进程可以看到它。
你需要做的是在结构体中有一个缓冲区,将目录名复制到其中,你需要使用 strcpy
char directory[10][200];

并且

strcpy (queue->directory[i], data->dir_name);

您需要检查字符串长度是否小于200(在这种情况下),如果过长则报告适当的错误。我不熟悉共享内存函数,不知道如何实现类似于malloc的功能; 如果您能够做到,那么您将把字符串复制到malloc的共享内存中,并将指向它的指针放入类似于代码中的数组中。从一个非常快速的谷歌搜索中,似乎像这样malloc 共享内存可能效果不佳。

+1 优秀的观点,任何立即字符串都会在编译时放置在程序的数据段中,即使它们没有声明。当您调用fork()函数时,整个程序的内存都会被复制,包括数据段。 - tay10r
我明白你的意思。我想做的是有一个数据结构(可能是2D数组?),它将包含到字符串值的索引。类似于Java中的Map<Integer,String>。我不希望char *directory [10]; 仅限于10个字符,我只想允许有10个条目。 - burtmacklin16
strncpy 不是最好的解决方案,它很容易使数组没有终止的 '\0' 空字符(即不是一个字符串)。 - Keith Thompson
@KeithThompson 你说得很对,既然字符串太长时没有什么有用的事情可做,我已经更新了我的答案以反映这一点。 - lxop

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