2015-01-09 128 views
0

我試圖理解爲什麼這個簡單的代碼導致了段錯誤,當我嘗試使用strcpy複製一些文字到共享內存中:與System V段錯誤共享內存

#include <stdlib.h> 
#include <sys/types.h> 
#include <sys/ipc.h> 
#include <sys/sem.h> 
#include <string.h> 

int main() 
{ 
    key_t key; 
    int flag,id; 
    char *buf; 

    flag=IPC_CREAT|0600; 
    if((key=ftok("myfile",12)) == -1) { 
     perror("key"); 
     exit(2); 
    } 
    printf("%X\n",key); 

    if((id=shmget(key,512,flag)) < 0) exit(1); 

    if((buf=shmat(id,0,0)) < 0) exit(2); 

    printf("PID %d, buf=%p\n",getpid(),buf); 
    system("ipcs -m | grep 512"); 
    sleep(20); 

    strcpy(buf,"Hello"); 
    sleep(100); 
    shmdt(buf); 
    exit(0); 
} 

,這裏是我所得到的:

C1A0DAB 
PID 12063, buf=0xffffffff8bc78000 
0x0c1a0dab 271941746 username  600  512  1 
Segmentation fault (core dumped) 

此外,該方法的PMAP表示:

00007f778bc78000  4K rw-s- [ shmid=0x10358072 ] 

我用指針buf猜錯了什麼,但我不知道如何改正這一點。

任何想法?

+0

共享存儲器,代碼需要的:#include 和 的#include user3629249

+0

這樣的:「#包括」是進程間通信,而不是共享內存。這:'#include '用於信號量,而不是共享內存 – user3629249

+0

沒有正確的#include語句,此代碼會導致編譯器引發17個警告。 (並且需要更正警告)BTW:鏈接時,訪問的庫是否正確? – user3629249

回答

2

請在啓用所有警告的情況下進行編譯(例如,gcc和clang至少爲-Wall)。

你錯過了#include <sys/shm.h>,所以你的編譯器假定smhat返回一個int,當它實際上返回一個void*。如果int和void*的大小不匹配,則說明存在問題。

添加包括,添加其他你也想念的,而你應該工作。

+0

非常感謝,確實#include 不見了。 – IbliSS

1

注意從編譯器中得到的警告。特別是,您將獲得:

file.c:22:5: warning: implicit declaration of function ‘shmat’ [-Wimplicit-function-declaration] 
file.c:22:13: warning: assignment makes pointer from integer without a cast 

它告訴你的問題是什麼 - 編譯器假設shmat返回(32位)的整數,而實際上它返回(64位)指針。所以,你失去了指針的前32位...

0

此信息,從http://web.cse.ohio-state.edu/~babic/Sem.shmem.new.pdf 需要被考慮在內:

重要: 信號和共享後回憶不顯式刪除留在系統 創建它們的進程將終止 ,甚至在用戶註銷時也會終止。

由於UNIX 支持這些資源的數量有限,這是 重要的是要確保所有創建 信號和共享內存是雷莫 在註銷前五個。

目錄 在/ usr /班/ cis660包括 S中的腳本文件 RSM 的.dat,提供方便的方式來刪除所有 信號燈和所有共同的回憶一次。

單個信號量或共享備忘錄 RY可以使用UNIX命令 再用ipcrm -s SEM#去除 或 再用ipcrm -m MEM# ,分別,其中SEM#和MEM#從UNIX命令獲得 IPCS ,其中列出了所有信號和共享存儲器