简体   繁体   English

为什么共享内存中的链表始终导致段错误?

[英]Why does my linked list in shared memory always lead to a segfault?

I have the following simple application. 我有以下简单的应用程序。 This has been stripped of error handling and such, to be, well, a minimal complete example. 除去了错误处理,这是一个最小的完整示例。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>

//#define SHM_SIZE 1024  /* make it a 1K shared memory segment */

struct node
{
    int x;
    struct node *next;
};

int main(int argc, char *argv[])
{
    struct node *root[argc+1];
    if (argc > 1)
    {
        int i;
        root[0]=  (struct node *) malloc( sizeof(struct node) );
        for (i=0; i<argc-1; i++)
        {
            root[i]->x = (int)(*argv[i+1]-'0');
            //root[i]->next=&root[i]+sizeof(struct node);
            root[i+1]=(struct node *) malloc( sizeof(struct node) ); //Okay, wastes a few ops
            root[i]->next=root[i+1];
        }
        free(root[i]->next);
        root[i]=NULL;
    }

    key_t key;
    int shmid;
    struct node *data;

    key = ftok("test1", 'O');
    shmid = shmget(key, (size_t)(sizeof(struct node)*1000), 0777 | IPC_CREAT);


    data = shmat(shmid, (void *)0, 0);
    printf("%p", &data);

    if (argc != 1)
    {
        int z=0;
        for (z=0;z<argc-1;z++){
            *(data+sizeof(struct node)*z)=*root[z];
            if (z) (data+sizeof (struct node)*(z-1))->next=(data+sizeof (struct node)*z);
        }
        (data+z)->next=0;

    }

if (argc)
    {
        printf("This is the routine that will retrieve the linked list from shared memory when we are done.");
        struct node *pointer;
        pointer=data;
        printf("%p", data);

        while (pointer->next != 0)
        {
            printf("\n Data: %i",pointer->x);
            pointer=pointer->next;
        }
    }
    /* detach from the segment: */
    if (shmdt(data) == -1)
    {
        perror("shmdt");
        exit(1);
    }

    return 0;
}

Basically, whenever I try to access the shared memory from the process that created it, my output looks good. 基本上,每当我尝试从创建共享内存的进程访问共享内存时,我的输出看起来都很好。 Every time I open the shared memory from a process that did NOT create it (argc=1) then the program segfaults. 每次我从未创建共享内存的进程(argc = 1)打开共享内存时,程序就会出现段错误。 I would appreciate it if someone could tell me why! 如果有人能告诉我原因,我将不胜感激!

Each time you attach a shared memory segment in a process, it is attached at some address which has no relation to the address in any other process that attaches the shared memory. 每次在进程中附加共享内存段时,它都会附加到某个地址,该地址与附加共享内存的任何其他进程中的地址无关。 So the pointers in the shared memory, while they point at other objects in the shared memory in the original (creating) process's shared memory, do not point at the shared memory in any other process. 因此,共享内存中的指针在指向原始(正在创建)进程的共享内存中的共享内存中的其他对象时,不会指向任何其他进程中的共享内存。

The net result -- if you want to store data structures in the shared memory, those data structures can't contain any pointers if you want them to work reasonably. 最终结果-如果您想将数据结构存储在共享内存中,那么如果您希望它们合理工作,则这些数据结构不能包含任何指针。 If you want pointer-like behavior, you instead need to use indexes into the shared momory, possibly as an array. 如果您想要类似指针的行为,则需要使用共享内存中的索引(可能作为数组)。 So you could do something like: 因此,您可以执行以下操作:

struct node {
    int x;     /* value */
    int next;  /* index of the next node */
};


struct node *data = shmat(...);  /* shm was sized for 1000 nodes */

/* link all of the data objects into a linked list, starting from data[0] */
for (int i = 0; i < 1000; ++i) {
    data[i].next = i+1;
}
data[999].next = -1;  /* using -1 for "NULL" as 0 is a valid index; */

for (int i = 0; i >= 0; i = data[i].next) {
    /* iterating down the linked list */
    data[i].x = 0;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM