Newsgroup: it.comp.lang.c++
Titolo: problema char*

salve a tutti NG...ragazzi ho un problema in questo prog-mino.
dunque: questa stupida funzione dovrebbe prendere in input un numero e dare
come output la stringa "disco1.car"se il numero č 1 e cosi via...
tutto funziona se nel programma eseguo la funzione una sola volta, se la
eseguo per la seconda volta il risultato č:
"disco1.car2.car" perche conserva in memoria il valore di string1, come fare
per risolvere il problema ??? grazie mille
char * disklabel(int disko)
    {
    char *string1="disco";
    char *string2=".car";
    char *s=itoa(disko,s,10);
    strcat(s,string2);
    char *string=strcat(string1,s);
    return string;
    }


stai facendo un'pò di casino con la memoria!
itoa inserisce in s la conversione di disko, ma mi dici in quale memoria la
mette se non ha spazio allocato???
stessa cosa per "strcat(s,string2);"
e successive...
Prova questa:
 char * disklabel(int disko)
     {
     char *string1="disco";
     char *string2=".car";
     char s[10] = {0}, stringaFinale[20] = {0};
     itoa(disko, s, 10); // ora s contiene il valore convertito
     strcat(s, string2); // ricorda che s deve essere suff. grande per contenere
string2
     strcpy(stringaFinale, string1);
     strcat(stringaFinale, s);
 
     return stringaFinale;
     }
--------------------------------
Inviato via 
http://usenet.libero.it

 }
Dimenticavo: stringaFinale[20] deve essere dichiarata come static e devi
prevedere la pulizia della sua memoria ad ogni ingresso nella funzione con
setmem.
Ciao


     }
Perché non provi con le string?
#include <string>
#include <sstream>
//Essendo un oggetto std::string con
//un nome del tipo "disco1.car" non molto grande,
//lo si puù ritornare per valore, benché questo comporti
//l'esecuzione dell'operatore "=" nel codice chiamante.
std::string disklabel(int disko)
{
        ostringstream oss;
        oss << disko;
        return ("disco" + oss.str() + ".car");
}
Saluti
-- 
Per l'e-mail rimuovere la frase in maiuscolo e gli underscore.

 ha scritto nel messaggio
news:81Z72Z86Z56Y1...@usenet.libero.it...


 
string1 per come l'hai definito puoi solo farlo puntare a un'altra area
di memoria, in quanto tu con 
char *string1="disco";
hai dichiarato che string1 è di tipo puntatore a char, e punta alla
stringa COSTANTE "disco", che si trova da qualche parte in memoria. Non
puoi modificare questa stringa, al limite puoi cambiare il valore
puntato, cioè far puntare string1 a un'altro array di caratteri.
Risolveresti il tuo problema utilizzando le stringhe e non gli array di
caratteri...
#include <string>
std::string string1="disco";
string1 è un oggetto stringa, e ci puoi fare quello che vuoi...


 #include <string>
Su questo hai ragione, le string sono meglio delle stringhe C-like

 caratteri, altrimenti il comportamento non è definito.
Umh, ti stai confondendo, quello che dici e' vero per:
char string1[]="disco";
ma non per:
char *string1="disco";
Se non ti sei solamente confuso, ma non sai la differenza, allora ti posto
una descrizione completa.
Per ora evito visto che magari ti sei solo confuso ma sai benissimo la
differenza.
(anche se sui libri di C++ queste cose sono un tantino meno approfondite per
ovvi motivi ;-)
A presto,
Tommy

 altrimenti il comportamento non è definito.
Ok prenoto il campo per sabato alle 18! :-) Scherzo, forse ti confondi:
char *stringa="qualcosa"; crea una stringa "qualcosa" in memoria
read-only, e fa puntare stringa ad essa. Non puoi modificarla, anche se
probabilmente qualche compilatore te lo permette...se fosse char
stringa[]="qualcosa"; avresti ragione tu, perchè creerebbe un array di
char e lo inizializzerebbe con i caratteri componenti la stringa
"qualcosa"..

 char *string1="disco";
Ok mea culpa. Complice il fatto che io la sintassi
char *string1="disco";
non l'ho mai usata e che quando dichiaro esplicitamente un char* č solo per
usarlo con l'allocazione dinamica, new delete e compagnia bella mi sono
sbagliato. Infatti quando mi serve una stringa C-like (non troppo spesso per
fortuna) la dichiaro sempre
char string1[]="disco";
o
char string1[100]="disco";
Evidentemente mi sono sbagliato e ho erroneamente supposto che
char *string1="disco";
corrispondesse semanticamente a quella forma che uso piů spesso:
char string1[]="disco";

 ha scritto nel messaggio
news:pan.2003.05.20.22...@home.com...


 
fstream...
cmq, puoi sempre utilizzare le strring e poi ritornare la stringa in
formato C corrispondente alla tua stringa
char * disklabel(int disko){
    std::string string1="disco";
    std::string string2=".car";
    std::string s=itoa(disko,s,10);
    std::string risultato=string1+s+string2;
    return string.c_str();
}
A occhio e alle 00:10 di sera dovrebbe andare bene :-)

     return string;
Dulcis in fundo. tutto questo brodo lo restituisci al chiamante, out of
scope. Ma fortuna vuole che se sei arrivato fin quì senza esplosioni la
stringa che ottieni è praticamente una costante pasticciata ma pur sempre
costante. Quindi al chiamante funziona. La prima volta... 
La senconda volta, l'area di memoria a cui punta string1 è sempre la
stessa, perchè è costante. Ed è quella che hai concatenato s. Quindi
continui concatenando in successione altra roba. Se la chiamassi un'altra
volta continueresti la concatenazione, e così via...
Finchè verrà il crash.

 caratteri, altrimenti il comportamento non è definito.
Scherzi?
Modificare il contenuto delle stringhe costanti ha un comportamento
indefinito. Non si può fare. 

 wrote in message
pan.2003.05.20....@despammed.com...

ok ok... pace.... ho ammesso la mia colpa. Credevo che char*
almanacco="usecondom"; equivalesse a char[] almanacco="usecondom"; ,
onestamanete uso sempre la seconda forma, la prima non l'ho mai usata.
ciao

 ciao
 
E non farlo più o conoscerai le ire di San Bjarne...e pure di SS.K&R :-)

 A occhio e alle 00:10 di sera dovrebbe andare bene :-)
No, non va bene. Il puntatore restituito da c_str() perde validità quando
l'oggetto std:string esce di scope al termine della funzione.
Max



Giusto...allora, meglio che certe cose non si scrivono a mezzanotte e
dintorni :-)
Ci riprovo, ma essendo l'una e mezza di notte mi preparo ad un altro
richiamo :-)
char *disklabel(int disko){
	char s[20];
        string string1="disco";
        string string2=".car";
        sprintf(s,"%d",disko);
        string risultato=string1+s+string2;
        char *ris_c=new char[risultato.size()+1];
        strcpy(ris_c,risultato.c_str());
        return ris_c;
}
Ok stavolta? :-)
Buonanotte a tutti

 Ok stavolta? :-)
Basta che scrivi a caratteri cubitali che il codice client è responsabile del
rilascio della memoria allocata. Purtroppo il nostro OP (xxx) vorrebbe tanto
[perché poi?] usare la chiamata a quella funzione direttamente come primo
argomento di fopen. Se usa la tua in quel modo, il memory-leak è inevitabile.
Per l'OP:
std::string disklabel( int  disko )
{  char s[60];
   sprintf(s,"disco%d.car",disko);
   return std::string(s);
 }
 fd = fopen( disklabel(1).c_str(), "wb" );
Max

 ha scritto nel messaggio
news:baefek$jq7$1...@newsreader.mailgate.org...


 qualcuno me lo spiega? merci
Per ciascun thread (discussione in un newsgroup)  l'op è colui che l'ha
generata postando il primo messaggio. Per quanto riguarda il thread
"problema char*" l'op eri tu.

 
In effetti il mio codice era una specie di "pezza"...è normale che la tua
soluzione è la migliore...per quanto riguarda il memory leak, quello che
dici è vero, ma chi proviene dal C è esperto di questi problemi, visto
che era consuetudine fare cose del genere. In C++ è pericoloso ed ha poco
senso, ma la funzione originale non era proprio C++...insomma, abbiamo
fatto un po'di schifezza :-)

     return string.c_str();
Brr... :-)
string.c_str() non è statico, per il chiamante sarà fuffa :-)

 In effetti il mio codice era una specie di "pezza"...
molto meglio qualcosa del ripo:
char *disklabel(int disko, char *buffer, int bufferSize) 
il chiamante si occupa di allocare buffer e comunicare la dimensione alla
funzione.
E' buona norma che la memoria dinamicamente allocata venga deallocata
nello stesso scope, onde evitare memory leaks molto probabili (dealloco
io? deallochi tu?). Altrimenti fai tornare una variabile statica.



In C c'erano due strade per risolvere il problema: utilizzare un buffer
allocato esternamente (la tua soluzione) oppure internamente, lasciando
la responsabilità al chiamante...il fatto è che in C++ sono entrambe
strade cattive in quanto un bel reference a string risolve il problema
magnificamente...