C 共享内存中的指针数组

C 共享内存中的指针数组,c,posix,C,Posix,我不熟悉共享内存和posix,所以在做一些基础工作时遇到了麻烦 我有以下几个节点: typedef struct Node{ int node_id; int process_id; struct Node* next; }Entry; 我创建了一个指针数组,每个位置都可以有一个链表。它的功能就像一个哈希表,有两个进程正在编辑它 因此,数组中的每个位置都可能有元素,但也可能有很多元素是空的 我在共享内存中放入了指针数组,而不是列表中的节点。这是一个大问题,因为进程1的节

我不熟悉共享内存posix,所以在做一些基础工作时遇到了麻烦

我有以下几个节点:

typedef struct Node{
    int node_id;
    int process_id;
    struct Node* next;
}Entry;
我创建了一个指针数组,每个位置都可以有一个链表。它的功能就像一个哈希表,有两个进程正在编辑它

因此,数组中的每个位置都可能有元素,但也可能有很多元素是空的

我在共享内存中放入了指针数组,而不是列表中的节点。这是一个大问题,因为进程1的节点在进程2中是不可见的,或者如下面所示

int shmid = shmget(ftok("./main.c", 30), (size_t)(node_num*sizeof(Entry *)), 0666 | IPC_CREAT);
if(shmid == -1){
    fprintf(stderr, "shmget error");
    exit(EXIT_FAILURE);
}
void* shared_memory = (void*)shmat(shmid, (void*)0, 0);
if(shared_memory == (void*)-1){
    frpintf(stderr, "shmat error");
    exit(EXIT_FAILURE);
}
Entry** HashTable = (Entry **)shared_memory;
对于该表,两个进程都将插入和删除节点。 我已经看到了这个问题的解决方案,但它需要固定的列表大小,其中是一个共享段内的节点池,但在我的例子中,它不是固定的,因为在执行过程中,该数字作为参数给出

我的数组用作哈希表,可以放置的项是有限的,所以让我担心的是

  • 从一开始,我将必须放入段X节点,并通过哈希函数连接它们

  • 如果我用
    shmget
    nodes\u num*sizeof(Entry)
    作为参数创建它们,我应该如何分配它们?因为我相信指针数组在实现中起着至关重要的作用,因为很多指针都是
    NULL

  • 那么,在共享内存段中实现此哈希表的最佳方法是什么

    编辑#1

    评论给了我一个想法,但我仍然不知道它是否是一个好的实现

    我的想法是保留我已经拥有的指针数组,并在共享内存中添加另一个数组
    size=nodes\u num并使第一个数组指向包含所有数据(节点)的第二个数组的特定位置


    主要用于IPC的共享内存。这意味着您可以将一些数据放在内存中,另一个进程将获得这些数据

    所以,您可以将指针数组附加到共享内存中,您将得到另一个进程中的所有指针,但两个进程都有不同的利害关系,因此进程1在该位置有不同的数据,进程2在其自身堆栈中有不同的数据

    例如,您在进程1的1000位置上共享一个指针位置1000“您好”插入数据后,您将向另一个进程共享1000个位置,而另一个进程转到1000个位置,它将读取该位置数据,然后您将得到分段错误,因为您要搜索的位置上没有任何内容

    希望你能理解这件事。如果您的案例不同,则将其视为无效。多谢各位

    我还创建了共享内存中的数据结构,如果您正在搜索,请告诉我,我将为您指路

    您可以像这样传递指针

    char **array;
    char *shared_memory;
    int i=0;
    array = (char **)shmat(shmid, (void*)0, 0);
    shared_memory = (char *)shmat(shmid, (void*)0, 0);
    array[i] = shared_memory;
    
    和wise一样,您可以将所有指针输入指针数组中。若您要打印所有指针位置,您将得到相同的结果

    你可以这样访问

    int j=0;
    fprintf(stdout,"%d",get_data[j++]->node_id);
    
    这是完整的代码:

    #include <stdio.h>
    #include <sys/ipc.h>
    #include <sys/shm.h>
    #include <stdlib.h>
    
    typedef struct Node{
        int node_id;
        int process_id;
        struct Node* next;
    }entry;
    
    entry **array;
    int shmid;
    static int i=0;
    
    void add_begin(entry **hptr_get){
    
    fprintf(stdout,"in add_begin\n");
    
    entry* shared_memory = (entry *)shmat(shmid, (void*)0, 0);
    if(shared_memory == (void*)-1){
        fprintf(stdout,"shmat error");
        exit(0);
    }
    array[i++] = shared_memory;
    
    shared_memory->node_id = 1;
    shared_memory->process_id = 1;
    
    shared_memory->next = *hptr_get;
    *hptr_get = shared_memory;
    }
    
    void print(entry **print_data){
    int j=1;
    while(print_data[j]){
    
        fprintf(stdout,"%d",print_data[j]->node_id);
        fprintf(stdout,"%d",print_data[j]->process_id);
        print_data[j++];
     }
    }
    
    int main(){
    
    int node_num = 10;
    key_t key;
    key = 4567;
    char ans;
    
       shmid = shmget(key, (size_t)(node_num*sizeof(entry)),0666|IPC_CREAT);
      if(shmid == -1){
        fprintf(stderr,"shmget error");
        exit(0);
     }
    
    array = (entry **)shmat(shmid, (void*)0, 0);
    
    entry *hptr = (entry *)shmat(shmid, (void*)0, 0);
    
     array[i++]=hptr;
    
    hptr = 0;
    
    do{
        add_begin(&hptr);
        fprintf(stdout,"Do you want to add another data in shared memory?(Y/N)\n");
        fscanf(stdin," %c",&ans);
       }while((ans=='y')||(ans=='Y'));
     array[++i] = 0;
     print(array);
     }
    
    #包括
    #包括
    #包括
    #包括
    类型定义结构节点{
    int node_id;
    int进程id;
    结构节点*下一步;
    }入境;
    条目**数组;
    int shmid;
    静态int i=0;
    作废添加开始(条目**hptr\U get){
    fprintf(标准输出,“在添加中开始”);
    条目*共享内存=(条目*)shmat(shmid,(void*)0,0);
    如果(共享内存==(无效*)-1){
    fprintf(标准输出,“shmat错误”);
    出口(0);
    }
    数组[i++]=共享_内存;
    共享内存->节点id=1;
    共享内存->进程id=1;
    共享内存->下一步=*hptr\U获取;
    *hptr_get=共享_内存;
    }
    作废打印(条目**打印数据){
    int j=1;
    while(打印数据[j]){
    fprintf(标准输出,“%d”,打印数据[j]->节点id);
    fprintf(标准输出,“%d”,打印数据[j]->进程id);
    打印_数据[j++];
    }
    }
    int main(){
    int node_num=10;
    钥匙(t)钥匙;;
    密钥=4567;
    查尔安斯;
    shmid=shmget(key,(size_t)(node_num*sizeof(entry)),0666(IPC|u CREAT);
    如果(shmid==-1){
    fprintf(标准,“shmget错误”);
    出口(0);
    }
    数组=(条目**)shmat(shmid,(void*)0,0;
    条目*hptr=(条目*)shmat(shmid,(无效*)0,0);
    数组[i++]=hptr;
    hptr=0;
    做{
    添加开始(&hptr);
    fprintf(stdout,“是否要在共享内存中添加其他数据?(Y/N)\N”);
    fscanf(标准输入、%c、&ans);
    }而((ans=='y')| |(ans=='y'));
    数组[++i]=0;
    打印(阵列);
    }
    
    您需要将实际节点放入共享内存中,然后每个节点内的指针都会指向共享内存。我很想这样做,但事实是我找不到方法。我遇到了很多问题。我不明白你为什么需要一系列指针。一个
    条目数组应该足够了。@user58697我认为它不够。条目数组意味着我在数组的每个位置都有一个条目项。我的数组是一个带有列表的哈希表,因此有些位置根本没有元素,有些位置的元素超过1。
    void*shared\u memory2=(void*)shmat(shmid,(void*)0,0)对于附加此内存段的不同进程,返回的指针可能不同。在这种情况下,
    ->next
    指针可能会指向创建进程的地址范围之外。将指针存储在shm(或(mmapped)文件)中毫无意义。应该存储索引或偏移量,而不是指针。我知道这种情况正在发生。我希望保留指针数组,并将所有数据都保存在共享段中。问题是我不知道该怎么做,请参考我编辑的答案,它可能会对你有所帮助。但我要求你们不要这样做,若你们的另一个进程需要数据,那个么就把数据本身放在共享内存中,而不是指向另一个进程的指针和信号,所以你们的另一个进程将处理那个信号,并进入共享内存,获取那个特定的数据,做进一步的工作。我和你现在的处境一样
    #include <stdio.h>
    #include <sys/ipc.h>
    #include <sys/shm.h>
    #include <stdlib.h>
    
    typedef struct Node{
        int node_id;
        int process_id;
        struct Node* next;
    }entry;
    
    entry **array;
    int shmid;
    static int i=0;
    
    void add_begin(entry **hptr_get){
    
    fprintf(stdout,"in add_begin\n");
    
    entry* shared_memory = (entry *)shmat(shmid, (void*)0, 0);
    if(shared_memory == (void*)-1){
        fprintf(stdout,"shmat error");
        exit(0);
    }
    array[i++] = shared_memory;
    
    shared_memory->node_id = 1;
    shared_memory->process_id = 1;
    
    shared_memory->next = *hptr_get;
    *hptr_get = shared_memory;
    }
    
    void print(entry **print_data){
    int j=1;
    while(print_data[j]){
    
        fprintf(stdout,"%d",print_data[j]->node_id);
        fprintf(stdout,"%d",print_data[j]->process_id);
        print_data[j++];
     }
    }
    
    int main(){
    
    int node_num = 10;
    key_t key;
    key = 4567;
    char ans;
    
       shmid = shmget(key, (size_t)(node_num*sizeof(entry)),0666|IPC_CREAT);
      if(shmid == -1){
        fprintf(stderr,"shmget error");
        exit(0);
     }
    
    array = (entry **)shmat(shmid, (void*)0, 0);
    
    entry *hptr = (entry *)shmat(shmid, (void*)0, 0);
    
     array[i++]=hptr;
    
    hptr = 0;
    
    do{
        add_begin(&hptr);
        fprintf(stdout,"Do you want to add another data in shared memory?(Y/N)\n");
        fscanf(stdin," %c",&ans);
       }while((ans=='y')||(ans=='Y'));
     array[++i] = 0;
     print(array);
     }