2010-03-19 12 views
9

Jestem początkujący w C. Podczas czytania kodu źródłowego gita znalazłem tę funkcję otoki wokół malloc.Owijanie 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; 
} 

Pytania

  1. Nie mogłem zrozumieć, dlaczego są one za pomocą malloc(1)?
  2. Co robi release_pack_memory i nie mogę znaleźć tej funkcji implementacji w całym kodzie źródłowym.
  3. Co robi #ifdef XMALLOC_POISON memset(ret, 0xA5, size);?

Mam zamiar ponownie użyć tej funkcji w moim projekcie. Czy to jest dobre opakowanie wokół malloc?

Każda pomoc będzie świetna.

+7

Kudos do odczytu kodu istniejących złożonych programów - Życzę więcej deweloperów zrobił. – Lars

+3

Na pytanie 2: Jego definicja znajduje się w pliku sha1_file.c (dotyczy pamięci obiektów git, prawdopodobnie), a jego prototyp znajduje się w git-compat-util.h. (Podpowiedź: tak długo, jak patrzysz na kod źródłowy git, użyj 'git grep release_pack_memory', aby go znaleźć!) – Cascabel

+1

@Lars: Thanks. @Jefromi: Dobra uwaga na temat 'git grep'. –

Odpowiedz

3
  1. malloc (0) nie działa na wszystkich platformach, a w takim przypadku przydział jeden bajt jest wykonany zamiast. Umożliwienie przydzielania bloków pamięci o długości 0 upraszcza logikę wyższego poziomu programu.

  2. Nie wiem.

  3. Dzięki wypełnieniu przydzielonej pamięci niezerową wartością, łatwiej jest znaleźć błędy w programie, w którym pamięć jest używana bez właściwej inicjalizacji: program w takim przypadku niemal natychmiast ulegnie awarii. Ponieważ zapełnianie pamięci zajmuje dużo czasu, jest zapakowane w preprocesor definiujący, więc jest kompilowany tylko w razie potrzeby.

+1

Zachowanie "malloc (0)" jest zdefiniowana implementacja. Zwraca wskaźnik NULL lub wskaźnik niepusty na zero bajtów danych (co, oczywiście, nigdy nie można usunąć). C99 §7.20.3 Funkcje zarządzania pamięcią: "Jeśli żądany rozmiar przestrzeni wynosi zero, zachowanie jest zdefiniowane przez implementację: zwracany jest wskaźnik zerowy lub zachowanie jest takie, jakby rozmiar był inną niezerową wartością niż , z tym że zwracany wskaźnik nie będzie używany do uzyskania dostępu do obiektu. " –

2

Dla Pytanie 1:

standard nie definiuje zachowanie malloc(0). To może zwrócić prawidłowy wskaźnik lub może zwrócić wartość NULL. Różne implementacje obsługują to inaczej, więc kod powraca do malloc(1), aby uzyskać spójne zachowanie.

Dla Pytanie 3:

Ustala zawartość bufora do czegoś „obcym”. W ten sposób twój kod ma nadzieję, że nie polegamy na zawartości będącej czymś specyficznym (którego malloc nie gwarantuje).

+0

Czy zaleca się używanie tego opakowania? –

+0

@Appu - zmiana wartości 0 na 1 i wykonanie operacji na membranie jest w porządku. Kość na podstawie zasad OOM zależy od tego, co piszesz. Ta zasada jest dobra dla narzędzia wiersza poleceń, które wykonuje jedną rzecz i kończy działanie. Ta zasada może, ale nie musi być dobra dla długiego serwera (czy chcesz zakończyć proces, czy chcesz wyczyścić bieżące żądanie i spróbować ponownie). Polityka nie jest akceptowalna dla ogólnej biblioteki, ponieważ zasady OOM powinny być rozstrzygane przez główną aplikację. –

+0

Dobra uwaga. Kod, który będę pisać, dotyczy biblioteki. Myślę więc, że powinienem unikać "umierania". –

1

nie jestem zaznajomieni z tej owijki, ale tutaj jest to, co jej robi

1 - jeśli size = 0 określono następnie przeznacza 1 bajt zamiast jeśli bazowy malloc nie zrobić

to przypuszczalnie zrobić tak, że dzwoniący może jeszcze zrobić bezpłatnie na nim (jak realloc)

2 Zakładam jej próbować wymusić podstawowy podsystemu pamięci spojrzeć trudniej pamięci

3 sił XMALLOC_POISON do bufora do znanego stanu Jest to powszechna praktyka, aby zapobiegać i wykrywać niepoprawne błędy spowodowane niezainicjowanymi danymi.

Po drugie - dlaczego chcesz owinąć malloc. Zacznij od pomysłu, co chcesz zrobić, a następnie zaimplementuj lub skopiuj implementację. Przyczyny owijania malloc

  1. detekcyjna
  2. analizy użycia
  3. pamięci łączenie
  4. debugowanie (jak XMALLOC_POISON)
  5. wymuszone kontroli

prawie wszystkie z nich mogą być wykonane z valgrind - który ma znacznie więcej.

„pisanie kodu solidne” książka ma dobry zestaw owijarki pamięci dla 1,4 i 5

+0

Dzięki za odpowiedź. Szczerze mówiąc, jestem trochę zagubiony w świecie C. Aby więc uniknąć błędów, czytam kod innych programów i dowiaduję się, jak piszą kod. –

+2

"jest to prawdopodobnie wykonane tak, że osoba dzwoniąca może nadal robić na nim darmowe" - nadal możesz zadzwonić za darmo lub dokonać ponownego przydziału na wskaźniku zerowym. Nie znam źródła git, ale najprawdopodobniej jest to zrobione, aby upewnić się, że zwrot 0 może być ostatecznie potraktowany przez wywołującego jako błąd, nawet jeśli wartość wejściowa wynosiła 0. Lub prawdopodobnie zapewnić, że wskaźniki do różnych 0- wielkościowe przydziały porównują różne ("to nie jest twój zerowy rozmiar bufora, więc to nie może być twoja walizka!"). –