2012-10-05 4 views
2

3 개의 정수와 배열을 포함하는 공유 메모리 세그먼트를 만들려고합니다. 세그먼트가 만들어지고 포인터가 첨부되지만 변수 (변경, 인쇄 등)의 값에 액세스하려고하면 세그먼트 화 오류가 발생합니다.공유 메모리의 변수에 액세스하는 방법

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

#define SIZE 10 

    int* shm_front; 
    int* shm_end; 
    int* shm_count; 
    int* shm_array; 
    int shm_size = 3*sizeof(int) + sizeof(int[SIZE]); 

int main(int argc, char* argsv[]) 
{ 
    int shmid; 

    //create shared memory segment 
    if((shmid = shmget(IPC_PRIVATE, shm_size, 0644)) == -1) 
    { 
     printf("error in shmget"); 
     exit(1); 
    } 

    //obtain the pointer to the segment 
    if((shm_front = (int*)shmat(shmid, (void *)0, 0)) == (void *)-1) 
    { 
     printf("error in shmat"); 
     exit(1); 
    } 
    //move down the segment to set the other pointers 
    shm_end = shm_front + 1; 
    shm_count = shm_front + 2; 
    shm_array = shm_front + 3; 

//tests on shm 
*shm_end = 10;    //gives segmentation fault 
printf("\n%d", *shm_end); //gives segmentation fault 

      //clean-up 
    //get rid of shared memory 
    shmdt(shm_front); 
    shmctl(shmid, IPC_RMID, NULL); 

    printf("\n\n"); 
    return 0; 
} 

내가 구조체에 대한 포인터를 역 참조하여 공유 메모리에 접근했지만, 세그먼트마다 고장 가지고 : 여기

내가 노력 코드입니다.

감사합니다. 이제 모든 세그먼트 오류가 발생하지 않았습니다.

+0

여기에 의견을 올리려고했지만 서식이 끔찍한 것으로 보입니다. 아래에서 가능한 답변을 참조하십시오. –

답변

2

, 당신은 뱉어 컴파일러를 야기한다 sys/shm.h을 포함하지 않은이 :

warning: implicit declaration of function ‘shmget’ 
warning: implicit declaration of function ‘shmat’ 
warning: implicit declaration of function ‘shmdt’ 
warning: implicit declaration of function ‘shmctl’ 

이 경고 숨길 것 int *shmat의 반환 값을 캐스팅 :

warning: assignment makes pointer from integer without a cast 

shmat이 정의되어 있지 않기 때문에 컴파일러에서 암시 적으로 void * 대신 int을 반환하게됩니다. . 반환 된 주소가 부호있는 정수에 맞지 않으면 정의되지 않은 동작 인 정수 오버플로가 발생하고 할당되지 않은 메모리 위치에 액세스하기위한 세그먼트 오류가 발생할 가능성이 큽니다.

void *을 반환하는 함수의 반환 값은 특히 이러한 오류를 catch하기 위해 캐스팅하지 말아야하며 항상 경고를 사용하도록 컴파일해야합니다.

+0

세분화 오류를 제거했습니다. 감사합니다. 그러나 위의 코드에서 print 문을 주석 처리하지 않은 경우 "10"대신 "0"이 표시됩니다. – user1723361

+0

@ user1723361 : shm_front가 아닌'shm_front'를 인쇄하고 있습니다. '10'입니다. – netcoder

+0

+1. 당신이 올바른지. 64 비트 빌드 인 경우 64 비트 포인터 여야하는 32 비트 int 반환 값 때문에 거의 확실하게 중단됩니다. –

0

이 정말, 정제 질문으로 구성되지만 포맷터를 폭파하고 읽을했다, 그래서 나는

어쩌면 난 그냥이 옆으로 찾고 있어요 ... 답변으로 이동하고있어했다 공유 메모리 블록을 포함하지 않는

shm_end = shm_front; 
shm_count=shm_front+1 
shm_array=shm_front+2; 

첫 번째 정수는 ... 선 아래로 등등 마우스 오른쪽 shm_front에서, 블록의 머리에 저장 될 것이다 다음과 같이하지만 포인터는되지 않을 것 오프셋 0에서 몇 가지 관련 정보, 왜 당신이 하나씩 각각 오프셋 ... 그냥 관측 모르겠어요.

+0

"front"와 "end"는 shm_array에 저장된 큐 배열을 나타 내기 위해 사용되었습니다. 배열에 대한 인덱스와 같은 역할을합니다. – user1723361

+0

대기열의 앞면과 뒷면? 따라서 front/end는 처음에는 같은 위치를 가리 킵니다. –

1

이 유일한 문제지만

int shm_size = 3*sizeof(int) + sizeof(shm_array[SIZE]); 

대부분의 아마 당신이 원하지 않는 어떤이 줄 경우 나도 몰라. sizeof(shm_array[SIZE])은 배열이 아닌 int 크기입니다. 원하는 경우 sizeof(int[SIZE])을 사용해야합니다.

그리고 일반적으로 공유 세그먼트에 대한 최신 인터페이스 인 shm_open을 훨씬 쉽게 사용할 수 있습니다. 파일 열기 및 매핑과 유사하게 작동하며 세그먼트 크기에 대한 제약이 적습니다. 코드에서

+0

대단한 캐치!폭발도 내가 그것을 인식하지 못했습니다 :) (self-grumble) –

+0

# 5 (어쩌면 # 4) 내가 structs = P를 사용하여 내 공유 메모리를 매핑하는 이유; one sizeof = 오류 가능성이 적습니다. – WhozCraig

+0

맞습니다. 배열에 충분한 공간을 할당하고 싶었습니다. 나는 그것을 고쳐 줄 것이다. – user1723361

관련 문제