2017-06-16 253 views
-4

在我的完整程序中出現「分段錯誤」後,我在Linux中使用共享內存(沒有多個進程)編寫了一個簡單的c程序。在Linux中使用共享內存時如何解決「分段錯誤(核心轉儲)」

我仍然得到相同的錯誤。我做錯了什麼?

謝謝!

#include<stdio.h> 
#include<stdlib.h> 
#include<sys/shm.h> 
#include<sys/ipc.h> 
#include<sys/types.h> 

void sys_err(char s[]) 
{ 
    perror(s); 
    exit(1); 
} 

int main(int argc, char *argv[]) 
{ 
    int shmid, *shmptr, *ptr; 

    if(shmid = shmget(IPC_PRIVATE, (10)*sizeof(int), 0666|IPC_CREAT)<0) 
     sys_err("Cannot shmget"); 

    if((shmptr=(int*)shmat(shmid,0,0))<(int*)0) 
     sys_err("Cannot shmat"); 

    shmptr[0]=1; // <----- error: "Segmentation fault (core dumped)" 
    //OR 
    *shmptr=1; // <----- error: "Segmentation fault (core dumped)" 
    //OR 
    ptr=shmptr; // <----- error: "Segmentation fault (core dumped)" 
    *ptr=1; 

    if(shmdt(shmptr)<0) 
     sys_err("Cannot shmdt"); 

    shmctl(shmid,IPC_RMID,0); 

    return 0; 
} 
+3

我不知道這是問題,但它是* a *問題:當您將'shmat'的結果作爲'<(int *)0'比較時,您正在調用* implementation specific *行爲,這可能會或者可能無法工作。取而代之的是與'-1'(即'==(int *)-1')進行比較。 –

+2

作爲我以前的評論的補充,指針本身就是* unsigned *整數。我不知道C規範說的是什麼,但是檢查一個指針是否小於零不是一個我認爲有效的操作(因爲按照定義指針不能是負數)。與'-1'(鑄造成一個指針)的直接平等比較,儘管如此,還是不​​錯的。 –

+4

編譯警告,一切都會清楚。 'shmid = shmget(...)<0'不會做你認爲它的作用。用'<'檢查返回值也是一個壞主意。 – Art

回答

3

我最終發現了這個問題。 實際上很小。

在這部分

if(shmid = shmget(IPC_PRIVATE, (10)*sizeof(int), 0666|IPC_CREAT)<0) 
    sys_err("Cannot shmget"); 

有 「()」 缺失以包圍這樣的孔表達式:

if((shmid = shmget(IPC_PRIVATE, (10)*sizeof(int), 0666|IPC_CREAT))<0) 
    sys_err("Cannot shmget"); 

現在它運行。 謝謝!