Shehab White
Shehab White

Reputation: 1

Trouble writing to a shared memory segment

....hi guys ,I always get 'Segmentation error' while running my code. what I know that this error happens when there is a problem writing to a file (I guess the same goes for shared memory) , I know the error comes from the for loop ,I tried every thing to solve this error but failed (I even removed the for loop and only typed *s = 'A').Any help please .

#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdlib.h>

main()
{
    //Shared memory parameters
    int shmid ;
    int shmsize = 14;
    key_t key = 2121;
    char *shm, *s;
    //Create SMS
    if ((shmid = shmget (key , shmsize, 0666 | IPC_CREAT)) == -1) { 
        perror ("Error in Creating the SMS");
        abort();
    }
    //Attatching the sms to the address space
    if (shm = shmat(shmid , NULL , 0) == (char *)-1) {    /*<<<< 23 */
        perror ("Error in attatching the SMS");
        abort();
    }
    int i ;
    s = shm;
    for(i = 0 ; i <= 63 ; i++)
        *s++ = (char)i;
        *s = NULL;    /*<<<< 33 what's the problem */
}

Also I get warnings in both 23 and 33

Upvotes: 0

Views: 893

Answers (1)

Mats Petersson
Mats Petersson

Reputation: 129314

You should listen to the compilers warnings (and you should get a warning for line 7, the one with main on it as well - if you don't, then you should add -Wall to the compiler switches).

So on line 23 it says "making pointer from integer without a cast" [1]:

  if (shm = shmat(shmid , NULL , 0) == (char *)-1)

This is because your line of code isn't doing what you think it should do. If we split it up into separate lines, then it's clearer, isn't it?

  shm = shmat(shmid , NULL , 0) == (char *)-1;
  if (shm)

So, shm becomes the result of "return value from shmat(...) == -1. Which hopefully is zero. Then you assign s to shm, which means that *s++ tries to write to address zero - which should definitely give a seg fault.

Fix this by adding parenthesis to make the assignment happen first, then the comparison (like the shmid = shmget a few lines above) - or split it up like this (my preferred solution):

  shm = shmat(shmid , NULL , 0);
  if (shm == (char *)-1)

This line:

                 *s = NULL;  //what's the problem

is wrong because you are trying to assign NULL (which is (void *)0, and thus a pointer) to a char value. Correct this by either of these two lines:

*s = '\0';
*s = 0;

As per comment below: You should also take care to size your shared memory to cover the content you want to store. Currently you are asking for 14 bytes, and then writing 64. This doesn't fail, but that's just because the size gets rounded up to 4096 bytes - it's important to not "lie" to the OS about what you are asking for - even if you sometimes get away with it...

[1] It's always helpful if you post the actual warning messages, that would save me having to compile the code to find the warnings...

Upvotes: 1

Related Questions