2010-03-19 2 views
9

나는 초보자이다. git의 소스 코드를 읽는 동안, 나는이 래퍼 함수가 malloc 인 것을 발견했다.Wrapping malloc - C

void *xmalloc(size_t size) 
{ 
    void *ret = malloc(size); 
    if (!ret && !size) 
     ret = malloc(1); 
    if (!ret) { 
     release_pack_memory(size, -1); 
     ret = malloc(size); 
     if (!ret && !size) 
      ret = malloc(1); 
     if (!ret) 
      die("Out of memory, malloc failed"); 
    } 
#ifdef XMALLOC_POISON 
    memset(ret, 0xA5, size); 
#endif 
    return ret; 
} 

질문

  1. 이해 할 수없는 이유를 그들이 사용하는 malloc(1)?
  2. release_pack_memory은 무엇을합니까? 전체 소스 코드에서이 기능 구현을 찾을 수 없습니다.
  3. #ifdef XMALLOC_POISON memset(ret, 0xA5, size);의 기능은 무엇입니까?

내 프로젝트에서이 기능을 재사용 할 계획입니다. 이 포장재는 malloc 주위에 좋은 포장지입니까?

도움이 될 것입니다.

이 표준은 malloc(0)의 동작을 정의하지 않습니다 : 질문 1에 대한

+7

명예의 메모리 래퍼의 좋은 세트가 있습니다 - 내가 더 많은 개발자가 않았다 바랍니다. – Lars

+3

질문 2 : 그 정의는 sha1_file.c에있다. (메모리는 git의 pack 객체와 관련이있다.) 프로토 타입은 git-compat-util.h에있다. (힌트 : git의 소스 코드를 살펴 본다면'git grep release_pack_memory'를 사용하십시오!) – Cascabel

+1

@Lars : 고마워요. @ Jefromi :'git grep'에 대한 좋은 지적. –

답변

3
  1. malloc (0)이 모든 플랫폼에서 작동하지 않는 경우 대신 1 바이트 할당이 이루어집니다. 0 길이 메모리 블록의 할당을 허용하면 프로그램의 상위 로직을 단순화합니다.

  2. 잘 모름

  3. 할당 된 메모리를 0이 아닌 값으로 채우면 적절한 초기화없이 메모리가 사용되는 프로그램에서 버그를 찾는 것이 더 쉽습니다. 이러한 경우 거의 즉시 프로그램이 중단됩니다. 메모리를 채우는 데는 시간이 걸리므로 사전 처리기 정의에 래핑되므로 원하는 경우에만 컴파일됩니다.

+1

'malloc (0)'의 동작은 정의 된 구현입니다. 0 바이트의 데이터를 가리키는 NULL 포인터 또는 널 (null)이 아닌 포인터를 반환합니다. 물론 이것은 역 참조 할 수 없습니다. C99 §7.20.3 메모리 관리 함수 : "요청 된 공간의 크기가 0이면 동작은 구현 정의 : null 포인터가 반환되거나 크기가 0이 아닌 값인 인 것처럼 동작합니다 반환 된 포인터는 객체에 접근하는데 사용되어서는 안된다. " –

2

. 그것은 유효한 포인터를 반환하거나 NULL을 반환 할 수 있습니다. 구현에 따라 다르게 처리되므로 코드가 일관된 동작을 얻으려면 malloc(1)으로 되돌아갑니다. 질문 3

는 :

는 '이상한'뭔가 버퍼의 내용을 설정합니다. 이 방법으로, 당신의 코드는 특정 내용에 의존하지 않기를 바란다. (malloc은이를 보장하지 않는다.)

+0

이 래퍼를 사용 하시겠습니까? –

+0

@Appu - 0에서 1로 변경하고 memset을 사용하는 것이 좋습니다. OOM 정책에서 죽는 것은 당신이 작성한 것에 달려 있습니다. 정책은 한 가지 일을 끝내는 명령 줄 유틸리티에 적합합니다. 정책은 수명이 긴 서버의 경우 좋을 수도 있고 그렇지 않을 수도 있습니다 (프로세스를 종료 하시겠습니까, 아니면 현재 요청을 정리하고 다시 시도 하시겠습니까). OOM에 대한 정책은 주 응용 프로그램에 의해 결정되어야하므로 정책은 일반 라이브러리에 허용되지 않습니다. –

+0

좋은 지적. 내가 쓸 코드는 도서관 용입니다. 그래서 나는 '죽는다'는 것을 피해야한다고 생각합니다. –

2

질문 2의 경우 : release_pack_memory는 sha1_file.c:570에 있습니다.크기 = 0 다음 지정된 기본 malloc을 수행하지 않은 경우는 1 바이트 대신 할당되었다 그래서

이 아마도 경우 -

1

여기 그것의

1 무엇을하고이 래퍼에 익숙하지 모르지만, 발신자가 여전히

이 나는 ​​가정 (realloc과 같은) 그것을 무료로 할 수 있도록 수행의 알려진 상태로 버퍼

3 XMALLOC_POISON 힘을 메모리 열심히보고 기본 메모리 서브 시스템을 강제로 시도 이것은 초기화되지 않은 데이터로 인한 이상한 버그를 방지하고 탐지하기위한 일반적인 방법입니다.

둘째로, 왜 malloc을 감싸고 싶습니까? 원하는 것을 생각한 다음 구현하거나 구현을 복사하십시오. malloc에 ​​배치하는 이유

  1. 가 누출 감지
  2. 는 사용 분석

의하면합니다 (XMALLOC_POISON 등)

  • 디버깅
  • 가 적용 풀링 메모리는 거의 모든 이들을 함께 할 수있는 valgrind - 훨씬 더 많은 일을합니다.

    '솔리드 코드를 작성하는'책은 기존의 복잡한 프로그램의 코드를 읽는 1,4 및 5

  • +0

    답해 주셔서 감사합니다. 솔직히, 저는 C 세상에서 약간 길을 잃었습니다. 실수를 피하기 위해 다른 프로그램 코드를 읽고 코드 작성 방법을 찾아야합니다. –

    +2

    "이것은 호출자가 여전히 자유로울 수 있도록 아마도 수행됩니다"- 당신은 여전히 ​​null 포인터에 free 또는 realloc을 호출 할 수 있습니다. 나는 자식의 소스를 모르지만 입력이 0 인 경우에도 0 반환이 호출자에 의해 오류로 처리 될 수 있는지 확인하기 위해 완료되었을 가능성이 높습니다. 또는 다른 0- 크기가 다른 할당은 서로 다릅니다 ("이것은 크기가 0 인 버퍼가 아니므로 가방이 아니어야합니다!"). –