2012-03-30 15 views
37
#include "stdio.h" 
#include "string.h" 

main() 
{ 

    char string[] = "october"; // october is 7 letters 

    strcpy(string, "september"); // september is 9 letters 

    printf("the size of %s is %d and the length is %d\n\n", string, sizeof(string), strlen(string)); 

    return 0; 
} 

uscita:Sizeof vs STRLEN

la dimensione di settembre è 8 e la lunghezza è di 9

C'è qualcosa di sbagliato con la mia sintassi o cosa?

+10

Si sta scrivendo oltre la fine della stringa 'stringa'. Questo è un comportamento indefinito. 'string' può contenere solo 8 caratteri (7 per" ottobre "e 1 per il terminatore null). Quando chiami 'strcpy', stai scrivendo 10 caratteri (9 per" settembre "e 1 per il terminatore null), il che significa che sei passato oltre la fine dell'array e stai sovrascrivendo la memoria adiacente. – Marlon

+11

Si noti che 'sizeof' è calcolato al momento * compile * dove' strlen' è il tempo di esecuzione. – Naveen

+5

@Naveen: essere consapevoli del fatto che non è necessariamente vero dove sono coinvolti VLA. – caf

risposta

1

L'array di destinazione è 8 byte (lunghezza di "ottobre" più \ 0) e si desidera inserire 9 caratteri in tale matrice.

man strcpy dice: Se la stringa di destinazione di un strcpy() non è abbastanza grande, potrebbe succedere di tutto.

Ti prego, dimmi che cosa si vuole veramente fare, perché questo cattivo odore lungo cammino

+0

Questo è il programma di test per comprendere il funzionamento di sizeof() – beparas

33

sizeof e strlen() fanno cose diverse. In questo caso, la vostra dichiarazione

char string[] = "october"; 

è lo stesso di

char string[8] = "october"; 

in modo che il compilatore può dire che la dimensione della string è 8. Lo fa al momento della compilazione.

Tuttavia, strlen() conta il numero di caratteri nella stringa in fase di esecuzione. Quindi, dopo aver chiamato strcpy(), string ora contiene "settembre". strlen() conta i caratteri e ne trova 9. Si noti che non è stato assegnato spazio sufficiente per string da mantenere "settembre". Questo è un comportamento indefinito.

3

l'output è corretto perché

primo formato stringa di dichiarazione è stata allocata dal compilatore che è di 7 + 1 (Ottobre è 7 byte & 1 byte per terminatore null al momento della compilazione)

seconda affermazione: sei copia settembre (stringa da 9 byte a 8 byte);

lì per te ottenuto dimensione del settembre come 8 byte (ancora strlen() non funzionerà per settembre non ha carattere nullo)

+1

La stringa letterale '" settembre "' contiene implicitamente il carattere null, quindi 'strlen()' funzionerà, se il programma non si è già arrestato (a causa della scrittura oltre la fine dell'array 'string') –

-1

È necessario eliminare buffer overflow problema in questo esempio. Un modo per farlo è utilizzare strncpy:

memset(string, 0, sizeof(string)); 
strncpy(string, "september", sizeof(string)-1); 
+1

No, no, no. 'strncpy()', nonostante il suo nome, è lo strumento sbagliato per fare qualsiasi cosa con ** stringhe **. Nell'esempio sopra, la 'stringa' risultante non sarà una * stringa * perché nessuno dei suoi 8 elementi conterrà un terminatore zero. – pmg

+0

Perché lo strumento sbagliato? Ho risolto il problema della terminazione della stringa. –

+0

È lo strumento sbagliato per le stringhe proprio perché non tiene conto del terminatore zero che esiste in ogni singola stringa per definizione (il design '' strncpy() 'lo rende utile solo per ... errr ... * non terminato stringhe*). Assicurati di avere spazio e usa 'strcpy()' (o, se puoi usare gli iso BSD, usa 'strlcpy()'). – pmg