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
shared_pid_atomis shared, butshared_pid_atom->atomi_pidwill point to memory local to the current process, that memory will not be shared.mallocorrealloc.