0

....大家好,我在运行代码时总是收到“分段错误”。我知道当写入文件出现问题时会发生此错误(我想共享内存也是如此),我知道错误来自 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 收到警告

4

1 回答 1

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. 返回值的结果。希望为零。然后分配sshm,这意味着*s++尝试写入地址为零 - 这肯定会给出段错误。

通过添加括号以首先进行分配来解决此问题,然后进行比较(如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] 如果您发布实际的警告消息总是有帮助的,这样我就不必编译代码来查找警告......

于 2013-02-23T16:23:41.607 回答