0

I am using Eclipse C/C++ IDE on Ubuntu and am trying to define a 2D of char as a shared memory between a parent-child processes and am using this :

void fill(char **p)
{
    printf ("int i=0;\n");
    int i=0;
    printf ("int j=0;\n");
    int j=0;
    for(i=0;i<3;i++)
    {
        for(j=0;j<3;j++)
        {
            p[i][j]=' ';
        }
    }
}


int shmid;
char **shmPtr;
if(shmid = shmget(2000, sizeof(char[3][3]), 0)!=-1)
{
    shmPtr = shmat(shmid, 0, 0); //attach shared memory to pointer
    fill(shmPtr);
}

Is this the right way to define the array or not? While trying to fill this array I get a

segmentation fault

.

2
  • 2
    Show the code. How are you filling it? How are you declaring shmid? Keep in mind that 2D arrays != double pointers. Commented Feb 18, 2013 at 16:23
  • are you checking the return id of shmget isn't -1? Commented Feb 18, 2013 at 16:27

2 Answers 2

1

Just what I suspected. Two-dimensional arrays ain't double pointers.

void fill(char p[3][3])
{
    int i, j;
    for (i = 0; i < 3; i++) {
        for (j = 0; j < 3; j++) {
            p[i][j] = ' ';
        }
    }
}

int shmid = shmget(2000, sizeof(char[3][3]), 0);
char (*shmPtr)[3] = shmat(shmid, 0, 0);
fill(shmPtr);
Sign up to request clarification or add additional context in comments.

Comments

0

When working with shared memory (actually dynamic allocated in general) I'd recommend you to use use the following arithmetic to access 2D data instead of "[i][j]":

*(pointer + row * ncols + col) = ...

Also, you should use character ' ' instead of the string " " (which is a const char*).In your sample, the fill function would be something like:

void fill(char *p, int rows, int cols)
{
    int i, j;
    for(i=0; i<rows; i++)
    {
        for(j=0;j<cols;j++)
        {
            /* p[i][j] = ' '; */
            *(p + i*cols + j) = ' ';
        }
    }
}

Another, even better, is to use memset:

void fill(char *p, int rows, int cols)
{
    memset(p, (int)' ', cols*rows);
}

And, a main sample:

int main()
{
    int shmid;
    void *shmPtr;
    char *shm;
    /* create the shared segment */
    if ((shmid = shmget(IPC_PRIVATE, sizeof(char) * (3*3), IPC_CREAT | 0666)) < 0) {
        perror("shmget");
        exit(1);
    }
    /* use it on the parent process */
    if ((shmPtr = shmat(shmid, NULL, 0)) == (char *) -1) {
        perror("shmat");
        exit(1);
    }
    shm = (char *)shmPtr;
    /* fill with spaces */
    fill(shmPtr, 3, 3);
    int i;
    /* some forks, sample */
    for (i = 0; i < 10; i++) {
        if (fork() == 0) {
                ... child workd ...
        }
    }
    ...
    shmctl(shmid, IPC_RMID, NULL);
    return 0;
}

One more thing, if possible, try using mmap instead of the SysV shared memory.

Comments

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.