无法写入共享内存段

时间:2013-02-23 15:35:09

标签: c linux

....大家好,我在运行代码时总是遇到'分段错误'。我知道这个错误发生在写入文件时出现问题(我猜共享内存也是如此),我知道错误来自for循环,我尝试了所有的事情来解决这个错误但是失败了(我甚至删除了for循环,只输入* s ='A')。请帮忙。

#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 */
}

我也在23和33中收到警告

1 个答案:

答案 0 :(得分:1)

您应该收听编译器警告(并且您应该收到第7行的警告,其中包含main的警告 - 如果您没有,则应添加-Wall编译器开关)。

所以在第23行它说“从没有演员的整数制作指针”[1]:

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

这是因为您的代码行没有按照您认为应该执行的操作。如果我们将它分成不同的行,那么它就更清楚了,不是吗?

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

因此,shm成为“shmat(...) == -1返回值的结果。希望为零。然后您将s分配给shm,这意味着*s++尝试写入地址为零 - 这肯定会给出一个seg错误。

通过添加括号以使分配首先发生,然后进行比较(如上面的几行shmid = shmget) - 或者将其拆分为这样(我的首选解决方案)来解决此问题:

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

这一行:

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

是错误的,因为您尝试将NULL((void *)0,因此指针)指定为char值。通过以下两行中的任何一行纠正:

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

根据下面的评论:您还应该注意调整共享内存的大小以覆盖您要存储的内容。目前你要求14字节,然后写64.这不会失败,但这只是因为大小被四舍五入到4096字节 - 重要的是不要向操作系统“撒谎”你所要求的 - 甚至如果你有时侥幸逃脱......

[1]如果您发布实际警告消息总是有帮助的,这将节省我必须编译代码以找到警告......