简体   繁体   中英

Array of pointers in shared memory

I'm new to shared memory and posix so I'm finding trouble doing some basic work.

I have some Nodes as following:

typedef struct Node{
    int node_id;
    int process_id;
    struct Node* next;
}Entry;

I created an array of pointers and in every position there can be a linked list. It functions as a hash table and there are two processes that are editing it.

So there is a chance that there are elements in every position of the array but also there can be a lot of them empty.

I have put in shared memory the array of pointers and not the nodes of the list. So that is a big problem since the node of process 1 are not visible by process 2 and otherwise as you can see below.

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;

To this table both processes will insert and delete nodes. I have seen a solution to this problem but it required fixed size of the list, where is a pool of nodes all inside the shared segment, but in my case it isn't fixed since the number is given as a parameter during the execution.

My array functions as a hash table, and the items that can be put are limited so the thing that is worrying me is

  1. that from the beginning I will have to put in the segment X Nodes and connect them through the hash functions.

  2. if I create them with shmget and nodes_num*sizeof(Entry) as argument, how am I supposed to allocate them ? Because I believe the array of pointers play a vital role in the implementation since a lot of the pointers are NULL

So what is the best way to implement this hash table in the shared memory segment?

EDIT #1

Comments gave me an idea but I still don't know whether it is a good implementation.

My idea is to keep the array of pointers that I already have, and ADD another one array in the shared memory with size = nodes_num; and make the first array pointing at certain position of the second one that contains all the data(nodes)

int shmid2 = shmget(ftok("./main.c", 30), (size_t)(node_num*sizeof(Entry )), 0666 | IPC_CREAT);
if(shmid2 == -1){
    fprintf(stderr, "shmget error");
    exit(EXIT_FAILURE);
}
void* shared_memory2 = (void*)shmat(shmid, (void*)0, 0);
if(shared_memory2 == (void*)-1){
    frpintf(stderr, "shmat error");
    exit(EXIT_FAILURE);
}
Entry* Data = (Entry *)shared_memory2;

Mainly shared memory used for IPC.It means you can put some data in memory and another process will get that data.

so, You can attach array of pointer in shared memory and you will get that all pointers in another process but both process have different stakes so process one have different data in that location and process 2 have different data in its own stack.

For example you are sharing one pointer location 1000 in process1 on 1000 location "hello" data inserted then you will share 1000 location to another process while another process go to 1000 location and it will read that location data then you will get segmentation fault because there is nothing on that location which you are going to search.

hope you understood this thing. if your case is different then put this as a NULL (void). thank you.

i have also created data structure in shared memory if you are searching that then tell me i will show you way.

you can pass pointer like this

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;

Like wise you can enter all pointers into array of pointers.if you will print all pointer location you will get same.

and you can access like this,

int j=0;
fprintf(stdout,"%d",get_data[j++]->node_id);

This is full code:

#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);
 }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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