Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

`shmget` Invalid argument error — is memory still allocated from a previous execution?

I have the following program to exercise using forks and shared memory.

#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h> 
#include <unistd.h> 
#include <sys/wait.h>

#include <sys/shm.h>
#include <sys/ipc.h>

int main() {
    int bignum = 1000000;
    
    key_t key = ftok(".", 'x');
    int shmid = shmget(key, sizeof(int)*bignum, IPC_CREAT | 0666);
    if (shmid < 0) {
        perror("shmget\n");
        return 1;
    }
    int *arr = shmat(shmid, NULL, 0);
    pid_t c1 = fork();
    if (c1==0) {
        pid_t c2 = fork();
        if (c2==0) {
            pid_t c3 = fork();
            if (c3==0) {
                arr[0] = 10;
            } else {
                arr[1] = 11;
            }
            wait(NULL);
            exit(0);
        } else {
            arr[2] = 12;
        }
        wait(NULL);
        exit(0);
    } else {
        arr[3] = 13;
        wait(NULL);

        for (int i=0; i<4; i++) printf("%d ", arr[i]);
        printf("\n");
    }


    shmdt(arr);
    shmctl(shmid, IPC_RMID, NULL);
    exit(0);
}

I previously ran this program using a smaller amount of shared memory and have now increased it to see if that affects the program in any way. When I run this I get:

shmget
: Invalid argument

I’ve seen this post: C linux shmget Invalid argument

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

I’ve tried following the advice, but I’m unfamiliar with ipcs and ipcrm. I ran ipcs in a terminal and it gave me some shared memory info. But I can’t tell which is the one allocated by the program, there’s a lot, and I can’t tell what is safe to remove or not.

It also seems odd to me that you wouldn’t just do this inside the C program itself, so that makes me wonder if there isn’t a better way to resolve this issue. I particularly don’t get why the calls to shmdt and shmctl don’t make this a non-issue. Is there some other way to "undo" memory sharing?


Edit: The question was closed because it is similar to this:

C – System V – remove shared memory segment

However, that uses code that is already in my code — so it doesn’t seem to answer the question.

>Solution :

The old program left a smaller shared memory segment lingering after it exited so attaching to it, requesting a bigger size, fails. You can start your new program by removing it:

key_t key = ftok(".", 'x');
int shmid = shmget(key, 1, 0666); // no IPC_CREAT

if (shmid != -1) { // ok, there was a memory segment there already
    shmctl(shmid, IPC_RMID, NULL); // remove it
}
// now create the new one
shmid = shmget(key, sizeof(int)*bignum, IPC_CREAT | 0666);
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading