Newsgroup: it.comp.lang.c
Titolo: Problemi con la free di un array di caratteri

Salve a tutti,
ho creato una routine che mi consente di sostituire in una stringa di
caratteri la parte terminale che rappresenta l'estensione di un nome file.
Il risultato dell'operazione č corretto ma quando cerco di chiamare la free
sul puntatore ritornato dalla mia funzione ho un errore del tipo "DAMAGE
after normal block" come se il puntatore che sto passando alla free non
fosse valido!
Qualcuno sa indicarmi dove sta l'inghippo?
--------------------- CODICE FUNZIONE -------------------------------
char * replaceExtension(char * oldString, const char * newExtension)
{
 char * copy = NULL;
 char * retval=NULL;
 char * temp=NULL;
 size_t sizeOldString = strlen(oldString);
 if (sizeOldString == 0)
  errore(STRING_MANIPULATION_ERROR, oldString, "replaceExtension", TRUE);
 if ((copy = (char * ) calloc(sizeOldString,sizeof(char))) == NULL)
  errore(MEMORY_ALLOCATION_ERROR, "copy", "replaceExtension", TRUE);
 strcpy(copy, oldString);
 //Cerco il punto dell'estensione
 temp = strstr(copy, ".");
 if (temp != NULL)
  //tronco la stringa
  temp[0] = '\0';
 retval = strcat(copy, newExtension);
 return retval;
}
-----------------------------------FINE CODICE-----------------------------
Grazie
bye
John

 vecchia.
mmm.... dici che la strcat non fa nessuna realloc per la stringa a cui
dev'essere aggiunta la nuova estensione?
ero convinto di si, ma probabilmente mi sbaglio. Ci vuole poco a
controllare....
comunque nel mio caso la nuova "estensione" non superava mai la vecchia....
quindi non poteva essere quello il problema...
mi chiedo perň come questi miei errori possano invalidare il puntatore in
modo da restituirmi quell'erroraccio quando chiamo la free()
ora proverň a vedere se con lo strlen +1 le cose si mettono a posto.
Grazie
Bye
John

 ora proverň a vedere se con lo strlen +1 le cose si mettono a posto.
La storia del fatto che non aggiungevi 1 alla strlen e' al 99.99% la 
causa - cosi' come tutte le volte che si scrive fuori dalle aree di 
memoria a se' riservate. strcat non fa realloc, e cmq nei casi in cui 
fai delle assunzioni ("la nuova estensione non supera mai la vecchia") 
e' meglio aggiungere assert. Rendono il codice piu' chiaro, robusto, e 
finita la fase di debug possono venir tolte automaticamente.
-- 
Mat/tia Belletti             - Graduate student @ 
cs.unibo.it
ICQ: 33292311                - email: 
mbel...@cs.unibo.it
IRC: RedGlow                 - site(s): 
http://mbellett.web.cs.unibo.it/
Red...@jabber.linux.it/Gaim
 - Linux user 299762 @ machine 213003

 dev'essere aggiunta la nuova estensione?
No. Come potrebbe?
Max

 memoria a se' riservate. strcat non fa realloc, e cmq nei casi in cui
Quindi quando faccio strcat devo essere sicuro che la stringa di
"destinazione" abbia già spazio allocato sufficiente per ricevere anche la
stringa da appendere, giusto?
Il problema sembra fosse proprio quello perché ora non ho più errori... :)
Torno comunque a porre la mia domanda in altri termini: il fatto di aver
scritto al di fuori della zona di memoria allocata è sufficiente per
"invalidare" il puntatore a quella zona di memoria e così far fallire la
free()????
Grazie
Bye
John

 ha scritto nel messaggio
news:crmtf5$2g5$1...@newsreader.mailgate.org...

Bah, a me non pare tanto difficile pensare di fare una realloc sulla base
della dimensione iniziale della stringa + la dimensione della nuova stringa
che aggiungo.
Ciao
John


SI.  Dipende da come viene fatta la gestione dell'area.
Scrivendo anche 1 solo byte al di fuori dell'area allocata potresti aver 
corrotto la lista.  In genere la lista e` gestita dalle funzioni di 
libreria e varia da compilatore a compilatore.


 stringa che aggiungo.
Il primo argomento di strcat identifica un array char qualsiasi. Da nessuna 
parte c'è scritto che quel array deve essere stato allocato con malloc.
Applicare 'realloc' a un puntatore che non è stato restituito da 'malloc' 
produce comportamento indefinito.
 
Max

 free()????
Ti parlo "da standard": scrivere al di fuori delle zone di memoria 
allocate invoca l'undefined behaviour, e quindi puo' succedere qualunque 
cosa, compresa quella a te successa.


 Ok, giusto!
"DAMAGE after normal block", direi che l'errore era dato da questo
(supponendo di non sforare con la nuova estensione). Quello che accade
e` che la tua libreria mette dei pattern particolari (poisoning) prima e
dopo l'area allocata e quando viene fatta una free controlla
l'integrita` di questi pattern. Nel tuo caso parte del pattern e` stato
sovrascritto dal terminatore di stringa e la libreria ti segnala che
probabilmente hai fatto una porcata da qualche parte.
Nota che questo comportamento non e` richiesto dallo standard, viene
fornito come aiuto al programmatore da alcuni compilatori/librerie, e di
solito e` attivo solo compilando in modalita` debug.
Luca
-- 
Home: 
http://kronoz.cjb.net
"Su cio` di cui non si puo` parlare e` bene tacere".
 Ludwig Wittgenstein

 Luca
Grazie per la spiegazione!
Bye
John