写入共享内存分段故障

时间:2016-05-11 10:12:47

标签: c segmentation-fault shared-memory strcpy

我想要做的只是在共享内存中写“嘿”,但它会被抛到那一行。非常简单的代码如下:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/fcntl.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <sys/shm.h>
#define SHM_SIZE 1024
#define FLAGS IPC_CREAT | 0644
int main(){
    key_t key;
    int shmid;
    if ((key = ftok("ex31.c", 'k')) == -1){ 
        exit(1);}        
    if ((shmid = shmget(key, SHM_SIZE, FLAGS)) == -1) {
            exit(1);}
    char* shmaddr;
    if( shmaddr=shmat(shmid,0,0) == (char*)-1){   //WRONG ARGUMENTS ??
            exit(0); }
    printf("opened shared memory\n");  //gets here
    strcpy(shmaddr, "hey");     //GETS THROWN HERE
    printf("after writing to memory\n"); //never get here

调试器给我的错误是:

  

编程接收信号SIGSEGV,分段故障。   主要的0x0000000000401966(argc = 1,argv = 0x7fffffffe068)at   ../ex31.c:449 449 strcpy(shmaddr,“嘿”); //在这里了解

1 个答案:

答案 0 :(得分:0)

问题是运营商优先级。在行

shmaddr=shmat(shmid,0,0) == (char*)-1)

然后,一元-运算符和强制转换运算符具有最高优先级,后跟==,后跟=,其优先级最低。所以你的代码结果等于

shmaddr=(shmat(shmid,0,0) == (char*)-1))

这是废话。

内部条件的分配是非常糟糕的编程习惯。如果你尝试的话,每个不太合适的编译器会给你一个警告。除了运算符优先级问题之外,很容易混淆=和==。此外,=运算符会为表达式引入副作用,因此将其与其他运算符混合可能会导致未定义的行为。也许最重要的是,put = inside条件通常会大大降低代码的可读性。

您的代码应写为:

shmaddr = shmat(shmid,0,0);
if(chmaddr  == (char*)-1){

重要的是要理解通过将这两行合并为1来获得 nothing 。生成的机器代码将是相同的,除了上述版本中缺少错误。