2013-09-04 7 views
6

Próbuję poprawić kod. Mam coś takiego:Zachowanie ponownego przydziału, gdy nowy rozmiar jest taki sam jak stary

typedef struct{ 
    ... 
    }MAP; 



    MAP* pPtr=NULL; 
    MAP* pTemp=NULL; 
    int iCount=0; 
    while (!boolean){ 
    pTemp=(MAP*)realloc(pPtr,(iCount+1)*sizeof(MAP)); 
    if (pTemp==NULL){ 
    ... 
    } 
    pPtr=pTemp; 
    ... 
    iCount++; 
    } 

Pamięć jest przydzielana dynamicznie. Chciałbym ograniczyć liczbę ponownych wywołań, aby kod był bardziej wydajny. Chciałbym wiedzieć, jak zachowałoby się realloc, gdyby nowy rozmiar był równy temu staremu. Czy połączenie będzie po prostu ignorowane?

+1

OT: Czuję, że '(iCount + 1) * sizeof (MAP)' wygląda ładniej ... – alk

+0

@alk: masz rację. Zmienię to. –

+0

Większość implementacji prawdopodobnie zwraca ten sam wskaźnik, ale niektóre mogą czasami używać 'realloc' o takim samym rozmiarze jak możliwość przeniesienia przydzielonego miejsca, aby ułatwić przyszłe przydzielanie. –

Odpowiedz

8

To nie jest określony w normie C. Wszystkie standardowe C gwarantowana jest : zawartość nowego obiektu będzie taka sama jak starego przedmiotu przed deallokacją, do mniejszej z nowych i starych rozmiarów.

Jednakże, jeśli używasz GNU libc, to mówi wyraźnie, aby zwrócić ten sam adres, patrz here dla szczegółów.

Jeśli nowy rozmiar jest określony tak samo jak w starym wielkości realloc gwarantowana jest do niczego nie zmieni i powrót tego samego adresu, który dał.

+2

'realloc' jest dostarczane przez GNU' libc', a nie przez gcc, który jest tylko kompilatorem. W wielu systemach gcc jest używany z bibliotekami innymi niż GNU libc. –

+1

@Keith Thompson Naprawiono, dzięki za wskazanie. –

3

Nie liczę na to, że realloc zachowuje się jak no-op, jeśli rozmiar się nie zmienia (chociaż wydaje się to rozsądne), ale wtedy nie musisz: jeśli wartość iCount się nie zmienił, nie wykonuj połączenia, aby ponownie przydzielić.

2

Norma C nie określa, co się stanie, więc jesteś na łasce wdrożenia. Nie mogę sobie wyobrazić żadnej przyzwoitej implementacji, która nie zwróci wskazanego wskaźnika, ale bezpieczną opcją jest sprawdzenie, czy rozmiar alokacji zmienił się we własnym kodzie. To również z pewnością pominie wywołanie funkcji.

(BTW, proszę nie rzucać wartości zwracanej z realloc. To nie jest konieczne i może ukryć niezdefiniowanej zachowanie jeśli zapomnisz #include <stdlib.h>.)

+0

Myślę, że sprawdzanie, czy odwołanie zwrotne zwraca wartość NULL jest krytyczne, ponieważ jeśli się nie powiedzie, otrzymam błąd segmentacji. O ile mi wiadomo, każde pojedyncze wywołanie realloc dostępne online sprawdza, czy dane wyjściowe mają wartość NULL. –

+0

@hhachem: następnie pomiń połączenie, jeśli wielkość alokacji się nie zmieni. –

Powiązane problemy