1

I am trying to put shared_pid_data in shared memory. I need to have a dynamic array, so I use malloc, I also tried using calloc getting the same result. The problem I am encountering is that the data I print is different from what I should get. On initialization instead of getting '0' I get what seems to me to be a memory address or I don't know what. The function print_statistics() calls very simple functions that perform a return from shared memory. The init_ipc() function worked perfectly and inserted int variables into shared memory, so I simply copied the function and adapted it to allocate a pid_t pointer, if I do a return of the structure shared_data_t I get null. At the time I create 'a' processes 2/5 or 3/5 of those fail.

#include "ipc.h"
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/sem.h>
#include <fcntl.h>     // O_CREAT, O_RDWR
#include <sys/mman.h>  // shm_open, mmap, PROT_READ, PROT_WRITE, MAP_SHARED
#include <sys/stat.h>  // S_IRUSR, S_IWUSR
#include <unistd.h>    // ftruncate, pid_t
#include <sys/types.h> // pid_t
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct {
    int energy_produced;
    int active_atoms;
    int waste;
    int activation_flag;
    int total_energy;
    int energy_consumed;
    int scissions;
    int activations;
    int energy_demand;
    int sim_duration;
    int energy_explode_threshold;
    int n_atomi_init;
    int min_n_atomico;
    int n_nuovi_atomi;
    int max_num_atomico;
    int min_num_atomico;
} shared_data_t;

typedef struct{
    pid_t master;
    pid_t alimentatore;
    pid_t attivatore;
    pid_t *atomi_pid;
    int dimensione;
} shared_pid_data;

static int shmidA;
static int semidA;

void init_ipc() {
    key_t key = ftok("shmfileI",65);
    shmid = shmget(key, sizeof(shared_data_t), 0666|IPC_CREAT);
    shared_data = (shared_data_t*) shmat(shmid, (void*)0, 0);
    key_t sem_key = ftok("semfileI", 75);
    semid = semget(sem_key, 1, 0666 | IPC_CREAT);
    semctl(semid, 0, SETVAL, 1);
}

void lockA() {
    struct sembuf sb = {(unsigned short) 0, -1, 0};
    semop(semidA, &sb, 1);
}

void unlockA() {
    struct sembuf sb = {(unsigned short) 0, 1, 0};
    semop(semidA, &sb, 1);
}

void atomSharedPidInit() {
    key_t key = ftok("Ashmfile",65);
    shmidA = shmget(key, sizeof(shared_pid_data), 0666|IPC_CREAT);
    shared_pid_atom = (shared_pid_data*) shmat(shmidA, (void*)0, 0);
    shared_pid_atom->atomi_pid = (pid_t*)malloc(sizeof(pid_t) * 10); // Initial capacity of 10 PIDs
    shared_pid_atom->dimensione = 0;
    key_t sem_key = ftok("Asemfile", 75);
    semidA = semget(sem_key, 1, 0666 | IPC_CREAT);
    semctl(semidA, 0, SETVAL, 1);
}

void atomSharedPidWrite(pid_t pid) {
    lockA();
    if (shared_pid_atom->dimensione % 10 == 0) {
        shared_pid_atom->atomi_pid = (pid_t*)realloc(shared_pid_atom->atomi_pid, sizeof(int) * ((size_t)shared_pid_atom->dimensione + 10));
    }
    shared_pid_atom->atomi_pid[shared_pid_atom->dimensione] = pid;
    shared_pid_atom->dimensione++;
    unlockA();
}

void print_statistics() {
    printf("Current state:\n");
    printf("Total energy: %d\n", get_total_energy());
    printf("Total energy consumed: %d\n", get_energy_consumed());
    printf("Total energy available: %d\n", get_energy_produced()); 
    printf("Total atomi attivi: %d\n", get_active_atoms());
    printf("Total scissions: %d\n", get_scissions());
    printf("Total activations: %d\n", get_activations());
    printf("Total scorie: %d\n", get_waste());
    printf("+---------------------------------------------------+\n");
}

int main(int argc, char *argv[]) {
    init_ipc();
    print_statistics();
    atomSharedPidInit();
    print_statistics();

    for (int i = 0; i < 5; i++) {
        atomoPID = fork();
        if (atomoPID == 0) {
            srand((unsigned int)(time(NULL) + getpid()));
            printf("wirite pid Shared data\n");
            atomSharedPidWrite(getpid());
            int numero_atomico = rand() % max_num_atomico + min_num_atomico;
            printf("%d %d %d ", numero_atomico, max_num_atomico, min_num_atomico);
            char num_atomico_str[10];
            sprintf(num_atomico_str, "%d", numero_atomico);
            execl("./a", "./a", num_atomico_str, NULL);
            exit(0);
        } else if (atomoPID < -1) {
            kill(getpid(), SIGINT);
            exit(EXIT_FAILURE);
        }
    }

    while(1){
        print_statistics();
        sleep(1);
    }

    return EXIT_SUCCESS;

}

this is the result I get by printing the data the first two times

+---------------------------------------------------+
Current state:
Total energy: 0
Total energy consumed: 0
Total energy available: 0
Total atomi attivi: 0
Total scissions: 0
Total activations: 0
Total scorie: 0
+---------------------------------------------------+
Current state:
Total energy: -461014896
Total energy consumed: 24901
Total energy available: 0
Total atomi attivi: 0
Total scissions: 0
Total activations: 0
Total scorie: 0
+---------------------------------------------------+

this is what I get by printing the data inside the while(1)

+---------------------------------------------------+
Current state:
Total energy: -1854515536
Total energy consumed: 22593
Total energy available: 5320
Total atomi attivi: 5349
Total scissions: 0
Total activations: 0
Total scorie: 5346
+---------------------------------------------------+
Current state:
Total energy: -1854515536
Total energy consumed: 22613
Total energy available: 5300
Total atomi attivi: 5349
Total scissions: 0
Total activations: 0
Total scorie: 5346
+---------------------------------------------------+
void atomSharedPidInit() {
    key_t key = ftok("Ashmfile",65);
    shmidA = shmget(key, sizeof(shared_pid_data), 0666|IPC_CREAT);
    shared_pid_atom = (shared_pid_data*) shmat(shmidA, (void*)0, 0);
    shared_pid_atom->atomi_pid = (pid_t*) shmat(shmidA, (void*)0, 0);
    shared_pid_atom->atomi_pid = (pid_t*)malloc(sizeof(pid_t) * 10);
    shared_pid_atom->dimensione = 0;

I edited like this but nothing changed

5
  • 4
    The problem is that you share only the structures themselves, but the pointers will point to non-shared data. So shared_pid_atom is shared, but shared_pid_atom->atomi_pid will point to memory local to the current process, that memory will not be shared. Commented Jul 5, 2024 at 14:12
  • So should I add 'shared_pid_atom->atomi_pid' to the shared memory in the same way I do with the struct? Commented Jul 5, 2024 at 14:15
  • 1
    Yes you need to allocate it as shared memory as well, not using malloc or realloc. Commented Jul 5, 2024 at 14:18
  • the fact that I need malloc and realloc since the size has to be dynamic, before I was using an array but it was not good since the size was defined. Commented Jul 5, 2024 at 14:20
  • 2
    You can't share malloc'ed memory, plain and simple. You have to do your own allocation within the shared memory segment. And instead of pointers, use indexes into the shared memory. Commented Jul 5, 2024 at 14:38

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.