-5

I am trying to attach a two dimensional (2D) array, existing in a shared memory segment, to a process in C. I get the following error in compilation:

main.cpp:52:22: error: invalid conversion from ‘void*’ to ‘int (*)[2]’ [-fpermissive]
  shm_assemble = shmat(shmid_assemble,0,0);

and the compile command is:

g++ main.cpp -o myworkshop

My code is this:

#include <iostream>
#include <cstring>
#include <ctime>
#include <cstdlib>
#include <cstdio>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/sem.h>
#include <ctype.h>

#include "myheader.h"

void perror_exit(char *message);
bool init(int argc, char * argv[], int *Y);

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

    if(argc<3) {
        perror_exit("Usage: ./myworkshop -Y <value>\n");
        return(-1);
    }
    int i=0,n=0,child_pid=0,Y=0,shmid_paint=0,shmid_assemble=0,shmid_check=0,shmid_y=0,painter_empty=0,painter_full=0,checker_full=0,checker_empty=0,assembler_full=0,assembler_empty=0,ex=0;
    int *pids = new int[8];

    kill_message *shm_y;
    message *shm_paint,*shm_check;
    int (*shm_assemble)[2];

    if (!init(argc,argv,&Y)){
        std::cout << "Something is wrong with the arguments, try again\n";
        exit(-2);
    }

    if(Y==0) return 0; // if no products are to be created the program should exit

    const int SHMSIZE = sizeof(message);                // Shared Memory size = the size of a message
    const int assembler_SHMSIZE = sizeof(int[3*Y][2]);
    printf("assembler_SHMSIZE is: %d\n", assembler_SHMSIZE);
    const int kill_SHMSIZE = sizeof(kill_message);
    // srand(time(NULL));

    /* --- Shared memory creation --- */
    shmid_paint = shmget(IPC_PRIVATE, SHMSIZE, IPC_CREAT | 0666);
    shmid_assemble = shmget(IPC_PRIVATE, assembler_SHMSIZE, IPC_CREAT | 0666);
    shmid_check = shmget(IPC_PRIVATE, SHMSIZE, IPC_CREAT | 0666);
    shmid_y = shmget(IPC_PRIVATE, kill_SHMSIZE, IPC_CREAT | 0666);

    shm_paint = (message*)shmat(shmid_paint,NULL,0);
    shm_assemble = (int **)shmat(shmid_assemble,0,0);
    shm_check = (message*)shmat(shmid_check,NULL,0);
    shm_y = (kill_message*)shmat(shmid
}

What am I doing wrong here?

I read this similar question but I either did not understand the answer correctly or the static size does not help in my case.

My goal is to have a two dimension array of [3*Y][2] integers where Y is given as an argument in main and is initiallized correctly in init function which I did not include here.

9
  • I don't think you need to cast the return value from shmat. Commented Nov 29, 2018 at 23:59
  • 2
    Your code and compiler are C++ (although using some C libraries and idioms). Do you want to do this in C, or do you want to do this in C++? Commented Nov 30, 2018 at 0:04
  • The suffix .cpp tells the compiler that you have C++ source so it applies C++ rules to that source. Don't tell it untruths — compilers do not like being lied to and find ways to get their own back when you do. Yes, they are very different languages, especially in the area of memory management. Commented Nov 30, 2018 at 0:05
  • C is C; C++ is C++; C-style C++ is still C++, even though it is using C++ in a particular way. There is negative value to confuse it. Don't pretend it is not important, because it is. Commented Nov 30, 2018 at 0:13
  • Well, you must be confused about that. I write C++, use C libraries and compile with g++, my file is .cpp but this problem I mention here is not about the language I use so I wrote and tagged C for simplicity. Is it clear now? @AnttiHaapala Commented Nov 30, 2018 at 0:15

1 Answer 1

2

Ok the answer was quite simple. I had to declare shm_write_assembler as int **. My initial int (shm_write_assembler)[2] was working in C, like in the related question I was using as an example but not in C++. Changing this made my code work like a charm.

Here is the corrected code:

#include <iostream>
#include <cstring>
#include <ctime>
#include <cstdlib>
#include <cstdio>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/sem.h>
#include <ctype.h>

#include "myheader.h"

void perror_exit(char *message);
bool init(int argc, char * argv[], int *Y);

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

    if(argc<3) {
        perror_exit("Usage: ./myworkshop -Y <value>\n");
        return(-1);
    }
    int i=0,n=0,child_pid=0,Y=0,shmid_paint=0,shmid_assemble=0,shmid_check=0,shmid_y=0,painter_empty=0,painter_full=0,checker_full=0,checker_empty=0,assembler_full=0,assembler_empty=0,ex=0;
    int *pids = new int[8];

    kill_message *shm_y;
    message *shm_paint,*shm_check;
    int **shm_assemble;

    if (!init(argc,argv,&Y)){
        std::cout << "Something is wrong with the arguments, try again\n";
        exit(-2);
    }

    if(Y==0) {
        delete[] pids;
        return 0; // if no products are to be created the program should exit
    }

    const int SHMSIZE = sizeof(message);                // Shared Memory size = the size of a message
    const int assembler_SHMSIZE = sizeof(int[3*Y][2]);
    printf("assembler_SHMSIZE is: %d\n", assembler_SHMSIZE);
    const int kill_SHMSIZE = sizeof(kill_message);
    // srand(time(NULL));

    /* --- Shared memory creation --- */
    shmid_paint = shmget(IPC_PRIVATE, SHMSIZE, IPC_CREAT | 0666);
    shmid_assemble = shmget(IPC_PRIVATE, assembler_SHMSIZE, IPC_CREAT | 0666);
    shmid_check = shmget(IPC_PRIVATE, SHMSIZE, IPC_CREAT | 0666);
    shmid_y = shmget(IPC_PRIVATE, kill_SHMSIZE, IPC_CREAT | 0666);

    shm_paint = (message*)shmat(shmid_paint,NULL,0);
    shm_assemble = (int**)shmat(shmid_assemble,NULL,0);
    shm_check = (message*)shmat(shmid_check,NULL,0);
    shm_y = (kill_message*)shmat(shmid_y,NULL,0);

    /* --- Semaphore creation --- */
    painter_empty = semget(IPC_PRIVATE,1,IPC_CREAT | 0666);
    painter_full = semget(IPC_PRIVATE,1,IPC_CREAT | 0666);

    checker_empty = semget(IPC_PRIVATE,1,IPC_CREAT | 0666);
    checker_full = semget(IPC_PRIVATE,1,IPC_CREAT | 0666);

    assembler_empty = semget(IPC_PRIVATE,1,IPC_CREAT | 0666);
    assembler_full = semget(IPC_PRIVATE,1,IPC_CREAT | 0666);

    delete[] pids;
}
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.