c - 无法写入共享内存段

标签 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 中收到警告

最佳答案

你应该听编译器警告(你应该得到第 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++ 尝试写入地址零 - 这肯定会产生段错误。

通过添加括号使赋值首先发生,然后进行比较(如上面几行的 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] 如果您发布实际的警告消息总是有帮助的,这将使我不必编译代码来查找警告...

关于c - 无法写入共享内存段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15042212/

相关文章:

c - C 中的 XOR 相同数据导致非零值。为什么?

c - 地址 0x0 未被堆栈、分配或(最近)释放

c - 启用从用户空间进程调试内核模块

linux - 将每 100 个 html 文件合并为 1 个

c++ - QTcpSocket 在几次成功连接后发出 "Connection Refused Error"?

c - 读取 AudioFileInitializeWithCallbacks 所需的回调? Apple 音频文件 API

c - 什么是 char i=0x80 以及为什么在位移时没有发生溢出

linux - xen 使用命令行创建新虚拟机

linux - 在linux内核/文档中编译特定程序

linux - dirname 的选项无效