c-写入共享内存分段故障



我只想在共享内存中写"嘿",但它被抛出了。非常简单的代码如下:

#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 memoryn");  //gets here
    strcpy(shmaddr, "hey");     //GETS THROWN HERE
    printf("after writing to memoryn"); //never get here

调试器给我的错误是:

程序接收到信号SIGSEGV,分段故障。0x0000000000401966在的main中(argc=1,argv=0x7fffffe068)../ex31.c:449 449 strcpy(shmadr,"嘿")//被扔到这里

问题在于运算符优先级。在线

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

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

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

这是无稽之谈。

内部条件赋值是非常糟糕的编程实践。如果你尝试,每一个半吊子的编译器都会给你一个警告。除了运算符优先级问题外,很容易混淆=和==。此外,=运算符为表达式引入了副作用,因此将它与其他运算符混合可能会导致未定义的行为。也许最重要的是,在条件中放入=通常会大大降低代码的可读性。

您的代码应该写成:

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

重要的是要理解,通过将这2行合并为1,您将一无所获。生成的机器代码将是相同的,除了在上面的版本中没有错误。

最新更新