2014-04-20 4 views
0

다음 코드를 작성했지만 코드는 여전히 이 메모리를 확장하는 데 실패했음을 알리는 EEERROR 메시지를 전달합니다.mremap 함수가 새 메모리를 할당하지 못했습니다.

int main() 
{ 
int size_of_mem = 1024 
int fd = shm_open("/myregion", O_CREAT | O_RDWR, S_IRWXO | S_IRUSR | S_IWUSR); 
    if (fd == -1) 
     printf("ERROR in shm_open \n") ; 

    if (ftruncate(fd, size_of_mem) == -1) 
     printf("ERROR in ftruncate \n") ; 

    int shm_address = mmap(0 , size_of_mem , PROT_READ | PROT_WRITE | PROT_EXEC ,MAP_SHARED , fd , 0) ; 

    if (shm_address == MAP_FAILED) 
    { 
     printf("Error mmapping the file \n"); 
     exit(EXIT_FAILURE); 
    } 
    int temp = mremap(shm_address , size_of_mem ,4000 , MREMAP_MAYMOVE) ; 
    if(temp < 0) 
    { 
     printf("EEEEEEEERROR\n") ; 
    } 
return 0 ; 
} 

답변

4

여기에 몇 가지 문제가 있습니다.

먼저, mmap()mremap() 반환 당신이 단지 int에 캐스팅되지해야 void* 포인터. 둘째

mremap()man page 상태 :

반환 값 성공시, mremap에

()는 새로운 가상 메모리 영역에 대한 포인터를 반환합니다. 오류시 MAP_FAILED 값 (즉, (void *) -1)이 반환되고 errno가 적절하게 설정됩니다.

따라서 temp < 0이 잘못되었습니다. temp == (void*)-1이어야합니다. mremap()은 int에 캐스트 할 때 0보다 작은 성공시 유효한 포인터를 반환 할 가능성이 전적으로 있습니다. 셋째

모두 mmap()mremap() 에러 발생시 errno (man page) 변수를 설정. 이 내용을 읽으면 정확히 무엇이 잘못되었는지에 대한 자세한 정보를 얻을 수 있습니다. 문자 오류 메시지를 출력하려면 perror() 기능 (man page)을 사용하십시오. 이를 위해서는 #include <errno.h>을 사용해야합니다. 오류 조건을 감지하면 네 번째

는, 당신은 항상 메시지를 인쇄하지만 대부분 실행을 계속 할 수 있습니다. 그건 말이되지 않습니다. shm_open()이 실패하면 즉시 반환하거나 exit(EXIT_FAILURE)으로 전화하십시오. SHM 파일을 열지 못하는 경우 다음 기능 중 아무 것도 작동하지 않습니다.

#include <error.h> 

int main() 
{ 
    int size_of_mem = 1024; 
    int fd = shm_open("/myregion", O_CREAT | O_RDWR, 
         S_IRWXO | S_IRUSR | S_IWUSR); 
    if (fd == -1) 
    { 
     perror("Error in shm_open"); 
     return EXIT_FAILURE; 
    } 

    if (ftruncate(fd, size_of_mem) == -1) 
    { 
     perror("Error in ftruncate"); 
     return EXIT_FAILURE; 
    } 

    void *shm_address = mmap(0, size_of_mem, 
          PROT_READ | PROT_WRITE | PROT_EXEC, 
          MAP_SHARED, fd, 0); 
    if (shm_address == MAP_FAILED) 
    { 
     perror("Error mmapping the file"); 
     return EXIT_FAILURE; 
    } 

    void *temp = mremap(shm_address, size_of_mem, 4000, MREMAP_MAYMOVE); 
    if(temp == (void*)-1) 
    { 
     perror("Error on mremap()"); 
     return EXIT_FAILURE; 
    } 
    return 0; 
} 

참고 :

  • 올바른 데이터 유형 (void*), mremap() 확인 올바른 오류, perror()의 사용이 더 많은 정보 오류를 인쇄 할

    따라서, 내 청소 버전은 다음과 같습니다 메시지, 함수의 실행을 끝내는 에러 경로.

  • 들여 쓰기가 정확합니다.
  • 함수 호출시 , 앞에 공백이 없습니다.
+0

나는 당신이 말한 것과 그 일을 적용했습니다! ,하지만 첫 번째 지점에서, 나는'int'에 반환 값을 캐스팅했습니다, 그리고 그것은 또한 반환 값을 캐스팅하지 않으며 작동합니다! 둘째, 메모리 주소가 음수 일 수 있습니다 (int로 캐스팅 한 경우에도 마찬가지 임) .. thanks in advanace. – hbak

+2

작동한다고해서 그것이 올바른 것을 의미하지는 않습니다. 예를 들어, 64 비트 시스템에서는 실패합니다. 32 비트 아키텍처에서도 여전히 잘못되었습니다. 포인터는 0에서 0xFFFFFFFF로 이동합니다.이를 "int"에 매핑하면 0 - 0x7FFFFFFF는 양수이고, 0x80000000 - 0xFFFFFFFF는 음수입니다. 그래서''int''에 대한 매핑과''temp <0'' 체크가 잘못된 것입니다. 0x81230000과 같은 유효한 포인터는 음의 정수로 매핑되기 때문에 오류로 취급합니다. –

+0

질문이 하나 더 있습니다. 'temp'를'unsigned int'로 만들면 'temp <0'조건이 작동합니까? – hbak

관련 문제