lore_majo ha scritto:
str = (char *) malloc (n*sizeof(char));
scanf("%s", str); --> fgets(str,strlen(str),stdin);
@lore_majo, in questo codice c'e' un errore MOOLTO subdolo.
Per prima cosa, e' buona norma (non obbligatorio, ma aiuta) usare come nome delle costanti scritte tutte in maiuscolo, e magari anche usare un nome significativo che aiuta a capire.
Ad esempio, invece di "n", "MAX_STR_LEN".
Seconda cosa: invece di usare la "malloc", usare la "calloc" (leggiti la documentazioni: le due funzioni NON HANNO lo stesso numero di parametri).
La differenza tra le due funzioni e' significativa: la "calloc" INIZIALIZZA il blocco di memoria allocato, con ZERO.
Non preoccuparti dei tempi: si parla di nanosecondi per blocchi di memoria di gigabyte: ci sono istruzioni assembler dedicate.
Ed ora vediamo l'errore:
fgets(str,strlen(str),stdin)
Qui' tu usi la "strlen", ma la strlen ritorna la lunghezza della stringa memorizzata in "str", NON la dimensione del buffer allocato.
Purtroppo in C/C++ non esiste una API standard che ti permetta di sapere la dimensione del buffer, ne devi tenere traccia tu in qualche modo.
Ora, hai tre tipi di rogne:
1) se "str" e' stato inizializzato con zero, "strlen(str)" ritorna ZERO, quindi stai dicendo alla fgets che il tuo buffer e' lungo ZERO: cioe' non hai spazio nemmeno per UN carattere
2) se "str" NON E' stato inizializzato e sfortuna vuole che non contenza NESSUN ZERO, poiche' la strlen e' stupida e cerca il primo zero che trova, rischi di passare una lunghezza che e' MAGGIORE DELLA DIMENSIONE DEL BUFFER, con il risultato che potenzialmente potresti andare a scrivere in aree di memoria riservate.
3) il CASO PEGGIORE, "str" contiene caratteri a caso ed anche uno zero in qualche posizione.
Questo vuol dire che strlen ritorna una lunghezza a caso compresa tra 0 e MAX_STR_LEN. Se hai cu.. /fortuna, c'e' abbastanza spazio per leggere la stringa in ingresso, altrimenti leggi solo un po' di caratteri e ti perdi il resto.
Il problema sta' nel fatto che questo pezzetto di codice OGNI TANTO FUNZIONA, OGNI TANTO NO. E non hai modo di prevederlo.
Quello che si chiama: "FUNZIONA PER SBAGLIO".
Ci sono una serie di nuove funzioni, con sufisso "_s" (per "safe") in cui si DEVE passare la lunghezza del buffer e che aiutano ad evitare questo tipo di pasticci.
AIUTANO, NON RISOLVONO.