How to allocate a linked list inside a structure in shared memory c

I have a linked list inside a C structure, or so I think. Structures:

//Structure of the domain list
typedef struct domains *domain_list;
    struct domains{
    char *domain;
    domain_list next;
}domains_node;

//Structure of the configuration of the server
typedef struct{
    int n_threads;
    domain_list domain_list;
    char* local_domain;
    char* named_pipe_statistics;
}server_config;

I tried to enter them into shared memory, I am sure that the structure is in order, but I do not know if the list is connected correctly (global variables used):

//Initialize shared memory
if((config_shmid = shmget(IPC_PRIVATE, sizeof(server_config), IPC_CREAT|0777)) < 0){
    perror("Error in config shmid\n");
    exit(1);
}
if((config = (server_config*)shmat(config_shmid, NULL, 0)) == (server_config *)-1){
    perror("Error in config shmat\n");
    exit(1);
}

if((config_domain_shmid = shmget(IPC_PRIVATE, sizeof(struct domains), IPC_CREAT|0777)) < 0){
    perror("Error in domain_list config shmid\n");
    exit(1);
}
if((config->domain_list = (domain_list)shmat(config_domain_shmid, NULL, 0)) == (domain_list)-1){
    perror("Error in domain_list config shmat\n");
    exit(1);
}

This is for the communication process. I need a dynamic (non-fixed) linked list inside a structure in shared memory. So, I need a way to allocate memory space for the new nodes that I create, and how to link them after. I am not with malloc now, but the answers to this question simply go as “adequate distribution”, and I don’t know what it is.

+4
1

, , , .

, .

, . domain char, , - .

, node, , , , . , next. , node. .

malloc free , node . , malloc NULL, .

, . , node, dnode . 0 , DNULL, size_t.

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/shm.h>



typedef struct DNode DNode;
typedef struct DList DList;

#define MAX_DNODE 32            // Max. domain string length
#define MAX_DLEN 64             // Max. number of list nodes

#define DNULL (MAX_DLEN + 1)    // NULL value

struct DNode {
    char domain[64];
    size_t next;
};

struct DList {
    DNode pool[MAX_DNODE];      // fixed-size space for nodes
    size_t npool;               // used space in pool
    size_t pfree;               // pointer to re-use freed nodes
    size_t head;                // global list head
};

DList *dlist;

DNode *dnode_alloc(void)
{
    if (dlist->pfree != DNULL) {
        DNode *node = dlist->pool + dlist->pfree;

        dlist->pfree = dlist->pool[dlist->pfree].next;
        return node;
    } else {
        if (dlist->npool < MAX_DNODE) return &dlist->pool[dlist->npool++];
    }

    return NULL;
}

void dnode_free(DNode *node)
{
    if (node) {
        node->next = dlist->pfree;
        dlist->pfree = node - dlist->pool;
    }
}

DNode *dnode(size_t index)
{
    return (index == DNULL) ? NULL : dlist->pool + index;
}

DNode *dnode_next(const DNode *node)
{
    return dnode(node->next);
}

DNode *dnode_push(size_t *head, const char *str)
{
    DNode *node = dnode_alloc();

    if (node) {
        strncpy(node->domain, str, sizeof(node->domain));
        node->next = *head;
        *head = node - dlist->pool;
    }

    return node;
}

void dnode_pop(size_t *head)
{
    if (*head != DNULL) {
        size_t next = dlist->pool[*head].next;

        dnode_free(&dlist->pool[*head]);
        *head = next;
    }
}



int main(int argc, char* argv[])
{
    int shmid;

    shmid = shmget(IPC_PRIVATE, sizeof(DList), IPC_CREAT | 0660);
    if (shmid < 0) exit(1);

    dlist = shmat(shmid, NULL, 0);
    if (dlist == (void *) (-1)) exit(1);

    dlist->head = DNULL;
    dlist->pfree = DNULL;
    dlist->npool = 0;

    dnode_push(&dlist->head, "Alpha");
    dnode_push(&dlist->head, "Bravo");
    dnode_push(&dlist->head, "Charlie");
    dnode_push(&dlist->head, "Delta");
    dnode_push(&dlist->head, "Echo");

    while (dlist->head != DNULL) {
        puts(dnode(dlist->head)->domain);
        dnode_pop(&dlist->head);
    }

    shmdt(dlist);

    return 0;
}
+7

Source: https://habr.com/ru/post/1612855/


All Articles