PDA

Visualizza la versione completa : [C/C++]Di nuovo i dilemmi dei puntatori..allocazione


Marco1995
21-01-2013, 15:08
Ciao ragazzi!Come da titolo vi sottopongo nuovamente un quesito :D .
Faccio prima ad esemplificare il tutto...in pratica la mia situazione questa:


#include <iostream>
#include <stdio.h>
#include <string.h>
using namespace std;
char* fun1(char parola[]);

int main()
{
char frase[10];
char *p;
printf("Inserisci la frase ");
gets(frase);
p = fun1(frase);

}
char* fun1(char parola[])
{
int i;
char* ritorno=new char (strlen(parola));
for (i = 0;parola[i]!='\0';i++)
if ((parola[i]>='a') && (parola[i]<='z'))
ritorno[i]=parola[i]-(char) 32;
else
ritorno[i] = '*';

return ritorno;
}

Eseguendo il codce con il debug,quando vado all'interno della fun1,noto che nella variabile char ritorno di tipo puntatore ci sono pi caratteri rispetto al numero di caratteri formanti la parola in ingresso.
Dato che ho fatto new char (strlen(parola))...il puntatore ritorno non dovrebbe contenere solo al massimo strlen(parola) caratteri?
Grazie per le risposte . . :ciauz: :ciauz:

oregon
21-01-2013, 15:42
Come saprai una stringa in C deve prevedere il terminatore null.

Quindi nella new devi prevedere il valore

[strlen(parola)+1]

e il NULL deve essere copiato nell'ultimo carattere della stringa ritorno (cosa che non fai).

MItaly
21-01-2013, 15:45
Hai fatto cinque grossi errori:
1. new char (strlen(parola)) sbagliato, questo alloca un singolo char e lo inizializza con strlen(parola) (convertito in un char); nel codice che segue quindi stai sforando abbondantemente dal buffer allocato (cosa che pu essere apparentemente indolore, come in questo caso, o portare a crash casuali); quello che intendevi scrivere new char [strlen(parola)];
2. ... ma comunque sbagliato, devi prevedere un carattere in pi per il carattere '\0' finale; quindi dovr essere new char[strlen(parola)+1];
3. in fun1 non termini la stringa "ritorno" con il '\0', motivo per cui in debug vedi pi caratteri di quanti ce ne siano: il debugger va avanti a leggere finch non trova un '\0' che per caso si trova l.
4. Nel main non deallochi la memoria restituita da fun1;
5. Mai usare la gets, l'utente pu inserire quanti caratteri gli pare e sforare dal tuo buffer; piuttosto, fgets.

Un abbozzo di correzione potrebbe essere:


#include <iostream>
#include <stdio.h>
#include <string.h>
using namespace std;
char* fun1(char parola[]);

int main()
{
char frase[10];
char *p;
printf("Inserisci la frase ");
fgets(frase, sizeof(frase), stdin);
// fgets acquisisce anche il newline finale, rimuovilo se credi
p = fun1(frase);
delete[] p;
return 0;
}
char* fun1(char parola[])
{
int i;
char* ritorno=new char[strlen(parola)+1];
for (i = 0;parola[i]!='\0';i++)
if ((parola[i]>='a') && (parola[i]<='z'))
ritorno[i]=parola[i]-(char) 32;
else
ritorno[i] = '*';
ritorno[i]=0;
return ritorno;
}

Marco1995
21-01-2013, 18:49
Grazie davvero per avermi risposto..grazie ancora per avermi spiegato le motivazioni ma anche per avermi fatto notare i miei numerosi errori D:
I caratteri terminatori della stringa proprio non li calcolavo seppure sapessi che esistessero...adesso si spiega il perch alcune volte mi apparivano risultati strani.
Riguardo alla deallocazione...beh vero mi sono dimenticato :dh:

Come al solito non deludete mai COMPLIMENTI

franzauker2.0
21-01-2013, 19:01
Diciamo che un modo alternativo quello di usare sprintf,per forzare l'aggiunta dello zero, giustapponendolo a un %s

Marco1995
21-01-2013, 19:26
Diciamo che un modo alternativo quello di usare sprintf,per forzare l'aggiunta dello zero, giustapponendolo a un %s
Frena,frena..non ti seguo.. :dh:

MItaly
21-01-2013, 21:31
Se per quello non ho ben capito neanch'io... :confused: la sprintf con lo specificatore "%s" vuole comunque una stringa gi terminata... :stordita:

Marco1995
22-01-2013, 16:01
Se per quello non ho ben capito neanch'io...
lol

Loading