将整数数组读写入共享内存

5
以下是我的共享内存的读写器代码:
读取代码-
int main(){
int shmid;
int *array;
int count = 5;
int i = 0;
key_t key = 12345;

shmid = shmget(key, count*sizeof(int), IPC_EXCL);

array = shmat(shmid, 0, SHM_RDONLY);

for(i=0; i<5; i++)
    {
        printf("\n%d---\n", array[i] );
    }

    printf("\nRead to memory succesful--\n");

    shmdt((void *) array);
    return 0;
}

写代码-
int main()
{
int shmid;
int *array;
int count = 5;
int i = 0;
int SizeMem;
key_t key = 12345;

SizeMem = sizeof(*array)*count;

shmid = shmget(key, count*sizeof(int), IPC_CREAT);

array = (int *)shmat(shmid, 0, 0);

array = malloc(sizeof(int)*count);

for(i=0; i<5; i++)
{
    array[i] = i;
}

for(i=0; i<count; i++)
{
    printf("\n%d---\n", array[i]);
}

printf("\nWritting to memory succesful--\n");

shmdt((void *) array);

return 0;
}

写入内存后,当我尝试读取时,输出的值为垃圾值。请问有人能解释一下我做错了什么吗?(输出显示全部为零)谢谢。

在写入部分,您正在使用malloc返回地址覆盖数组指针,并写入堆分配而不是共享内存。malloc是不必要的。 - Duck
你在从shmat返回值后分配数组内存。这实际上会丢弃这些值。 - Laz
1
@AnshDavid测试了你的代码,删除了我在答案中提到的那一行,现在在我的机器上运行得很好。应该没问题了。 - oyss
4个回答

4
在写入部分,您在获取共享内存地址后使用了malloc(),因此它将被覆盖。您应该删除malloc()行。
在读取部分,for循环应该像这样:
printf("\n%d---\n", array[i] );

1
在编写代码中,您试图将共享内存附加到数组变量上,并在下一步中通过调用malloc将其分配给用户空间(堆)中的新位置。
因此,您正在失去共享内存所在的位置,并将其写入由malloc分配的新数组。
array = (int *)shmat(shmid, 0, 0);
array = malloc(sizeof(int)*count);

如果您想在用户空间中使用数组,请使用不同的指针,或删除那一行malloc代码。共享内存将分配您创建时指定的内存,您无法通过其他方式后期分配内存。

1
你的 malloc 在这里覆盖了 shmat 的返回值。你没有写入共享内存,而是写入了刚刚 malloc 的内存。
array = (int *)shmat(shmid, 0, 0);

通过删除这行代码,在我的机器上你的代码运行正常。

array = malloc(sizeof(int)*count);


1

将数据留在内存段的指定偏移量处,这可以在编译时固定或放置在共享内存段中某个已知位置的字段中。

使用malloc()为指针分配内存的内存是私有的,仅适用于该进程。因此,在尝试在另一个进程中访问该指针时(除了malloc它的进程之外的其他进程),您可能会访问无效的内存页或映射到另一个进程地址空间的内存页。因此,您可能会收到segfault。

如果您正在使用共享内存,则必须确保要向其他进程公开的所有数据都在共享内存段中而不是进程的私有内存段中。

您可以尝试将数据留在内存段的指定偏移量处,这可以在编译时具体定义或放置在共享内存段中某个已知位置的字段中。

通过从代码中删除malloc调用,您的代码将正常工作。我已经尝试过它,它运行良好。


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