1

i want to share an array between 2 process (a master and a child). I have to use shared memory as a requirement of the project. But how can initialize the array? It give me back cast error and i didn't found anything that can help in other questions..Thanks

the warning says:

master.c: In function ‘main’:
master.c:17:14: warning: assignment to ‘int’ from ‘int *’ makes integer from pointer without a cast [-Wint-conversion]
   17 |    *nodeList = (int*)shmat(shmid,NULL,0);

master.c :

#include "config.h"


int main(int argc, char const *argv[]){
    pid_t userList[SO_USERS_NUM];
    int nodeList[SO_NODES_NUM];
    char *argsUser[3] = { CHILD_NAME };
    char *argsNode[3] = { NODE_NAME };
    int userID = -1;
    int nodeID = -1;
    int shmid;
    shmid = shmget(SH_KEY,SO_NODES_NUM*sizeof(int),IPC_CREAT);
    if(shmid == -1) {
        perror("shmget error");
        exit(EXIT_FAILURE);
    }
   *nodeList = (int*)shmat(shmid,NULL,0);
   // shmdt((void *) nodeList);
#ifndef SO_USERS_NUM
    printf("Error in main:  SO_USERS_NUM not defined");
#endif
    for (int i = 0; i < SO_NODES_NUM; i++) {
        ++nodeID;
        char test[100];
        pid_t pid = fork();
        switch (pid) {
            case 0:
                sprintf(test, "%d", nodeID);
                argsNode[1] = test;
                argsNode[2] = NULL;
                execvp(argsNode[0], argsNode);
                exit(EXIT_FAILURE);
                break;
            case -1:
                printf("Error in main:  fork failed");
                break;
            default:
                printf("master: launch node %d (pid %d)\n",nodeID,pid);
                nodeList[nodeID] = pid;
                break;
        }
    }
    for (int i = 0; i < SO_USERS_NUM; i++) {
        ++userID;
        char test[100];
        pid_t pid = fork();
        switch (pid) {
            case 0:
                sprintf(test, "%d", userID);
                argsUser[1] = test;
                argsUser[2] = NULL;
                execvp(argsUser[0], argsUser);
                exit(EXIT_FAILURE);
                break;
            case -1:
                printf("Error in main:  fork failed");
                break;
            default:
                printf("master: launch user %d (pid %d)\n",userID,pid);
                userList[userID] = pid;
                break;
        }
    }
    printf("\n");
    
        for (int i = 0; i < SO_NODES_NUM+SO_NODES_NUM; i++)
        {
            int pid_finished = wait(NULL);
            for (int s = 0; s < SO_NODES_NUM; s++)
            {
                if(pid_finished == nodeList[s])printf("\nMaster finished to wait a child node. PID: %d",pid_finished);
            }
            for (int y = 0; y < SO_USERS_NUM; y++)
            {
                if(pid_finished == userList[y])printf("\nMaster finished to wait a child user. PID: %d",pid_finished);
            }
            
        }
        
    return 0;
}

user.c :

#include "config.h"

int main(int argc, char const *argv[])
{
    int shmid = shmget(SH_KEY,SO_NODES_NUM*sizeof(pid_t),IPC_EXCL);
    printf("i'm a child");
    int* nodeList = (int*)shmat(shmid, NULL, 0);
    printf("\n");
    for (int i = 0; i < SO_NODES_NUM; i++)
    {
        printf("\nNODE: %d",nodeList[i]);
    }
    return 0;
}

in config.h :

#define KEY_QUEUE 0x200800  

#define SH_KEY 123456
/*
   NODE_NAME name of nodes's code lauched by execvp
*/
#define NODE_NAME "./node"
/*
   CHILD_NAME name of users's code lauched by execvp
*/
#define CHILD_NAME "./user"
3
  • NodeList is a pointer, you dereference a pointer to an integer and then try to assign it to a type of int *, and keep in mind that in C it's legal to assign void* to int* without a cast to the type-cast is uneeded. Commented Jul 16, 2022 at 14:50
  • So, what i have to change? line : *nodeList = shmat ? Commented Jul 16, 2022 at 14:51
  • I have rolled back your edit. Do not make substantive changes to a question after it has received answers. If you have another question then pose it as another question. Commented Jul 16, 2022 at 16:24

1 Answer 1

3

In your program, this ...

    int nodeList[SO_NODES_NUM];

... declares a local array. You could conceivably copy its contents into shared memory, but you cannot move it. An object's address is its most fundamental identity. Two objects with different addresses are different objects.

This ...

   *nodeList = (int*)shmat(shmid,NULL,0);

... attempts to assign the (pointer) value returned by shmat() to the (int) first element of nodeList. It is 100% equivalent to

    // WRONG
    nodeList[0] = (int *) shmat(shmid, NULL, 0);

That's wrong on at least two levels, and it is the source of the compiler diagnostic you reported.

The shmget() is creating an object in shared memory for you. You don't overlay that on another declared object. Rather, you just access it via the provided pointer. Probably you want something more like:

int *nodeList;  // declared as a pointer, not an array

// ...

int shmid = shmget(SH_KEY,SO_NODES_NUM*sizeof(int),IPC_CREAT);

// ...

// assign to nodeList itself, not to an object to which it points
nodeList = shmat(shmid, NULL, 0);
Sign up to request clarification or add additional context in comments.

3 Comments

OK, now it compile but...when i try to add an element: it give me back segmentation fault...why? When i do : nodeList[nodeID] = pid;
This problem borne cause i want that the child read this memory shared by father and print the element in the array. But, it doesn't do that and print only ("i'm a chile), when first of all the program worked
@MatteoPagliarello : That is a different question, and dealing with in comments is not appropriate. New problem - new question.

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.