2013-09-04 11 views
6

Sto provando a rendere un codice più efficiente. Ho qualcosa di simile:Comportamento di realloc quando la nuova dimensione è uguale a quella precedente

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++; 
    } 

La memoria viene allocata dinamicamente. Vorrei ridurre le chiamate realloc per rendere il codice più efficiente. Mi piacerebbe sapere come si comporterebbe realloc se la nuova dimensione è uguale a quella vecchia. La chiamata sarà semplicemente ignorata?

+1

OT: Mi sembra '(iCount + 1) * sizeof (MAP)' almeno sembra più bello ... – alk

+0

@alk: hai ragione. Lo cambierà. –

+0

La maggior parte delle implementazioni probabilmente restituisce lo stesso puntatore, ma alcune potrebbero talvolta utilizzare un 'realloc' con le stesse dimensioni di un'opportunità per riposizionare lo spazio allocato per rendere più facili le allocazioni future. –

risposta

8

Non è specificato nella norma C. Tutto di serie C garantito è : il contenuto del nuovo oggetto deve essere uguale a quello del vecchio oggetto prima della deallocazione, fino al minore tra le nuove e le vecchie dimensioni.

Tuttavia, se si utilizza GNU libc, si dice esplicitamente di restituire lo stesso indirizzo, vedere here per i dettagli.

Se la nuova dimensione specificata è la stessa della vecchia dimensione, realloc è garantito per non modificare nulla e restituire lo stesso indirizzo che hai dato.

+2

'realloc' è fornito da GNU' libc', non da gcc, che è solo il compilatore. Su molti sistemi, gcc è usato con librerie diverse da GNU libc. –

+1

@Keith Thompson Risolto, grazie per aver segnalato. –

3

Non vorrei contare su realloc che si comporta come un no-op se la dimensione non cambia (anche se sembra una cosa ragionevole da fare), ma poi non è necessario: se il valore di iCount non è cambiato, non effettuare la chiamata a realloc.

2

Lo standard C non specifica cosa accadrà, quindi sei in balia dell'implementazione. Non riesco a immaginare un'implementazione semi-decente che non restituisca il puntatore passato, ma l'opzione sicura è quella di verificare se la dimensione dell'allocazione è cambiata nel proprio codice. Ciò salterà sicuramente anche una chiamata di funzione.

(a proposito, si prega di non cast del valore restituito da realloc. Non è necessario e potrebbe nascondere un comportamento indefinito se si dimentica di #include <stdlib.h>.)

+0

Penso che controllare se realloc restituisca NULL è fondamentale, poiché se fallisce, finisco con un errore di segmentazione. Per quanto ne so, ogni singola chiamata realloc disponibile online verifica se l'output è NULL. –

+0

@hhachem: quindi salta la chiamata nel caso in cui la dimensione dell'allocazione non cambi. –