|
|
|
![]() |
|
Strumenti |
![]() |
#1 |
Senior Member
Iscritto dal: Mar 2003
Città: Rimini
Messaggi: 1843
|
[Esercizio C] Spiegare dov'è l'errore nel seguente codice
Mi sono trovato a fare questo esercizio ma non ho capito bene dov'è l'errore e come correggerlo.
Alla prima chiamata ad f() crasha nel momento in cui accede a *str2. Penso lo scopo sia quello di memorizzare str2 in str1. str1 non causa problemi, è str2 a causare il crash. Mi sapete dare un indizio del motivo per cui succede? Sono molto insicuro sulla gestione di str2 perchè è un array. So che essendo str1 un puntatore posso eseguire tutte le operazioni di aritmetica con i puntatori del tipo *(string1+1) per accedere al secondo elemento nell'array e così via, invece con la dichiarazione string2[] non sono certo che questo si possa fare. Codice:
void f(char *str1, char *str2) { //while( *str1++ != 'a' ) would work, str2 is the problem while( *str++ = *str2++ ); } int _tmain(int argc, _TCHAR* argv[]) { char *string1="test"; char string2[256]; f(string1, string2); cout << string1 << string2 << endl << endl; return 0; } |
![]() |
![]() |
![]() |
#2 |
Senior Member
Iscritto dal: Feb 2004
Città: milano
Messaggi: 2148
|
Ciao allora ti metto in bold le cose che vedo di errori di sintassi poi passimoa alla logica.
Codice:
void f(char *str1, char *str2) { //while( *str1++ != 'a' ) would work, str2 is the problem while( *str1++ = *str2++ ) ; //str non esiste la var è str1 } int _tmain(int argc, _TCHAR* argv[]) { char *string1="test"; char string2[256]; f(string1, string2); cout << string1 << string2 << endl << endl; return 0; } Secondo me il problema è copiare str1 in str2 e non il contrario e io farei così: Codice:
void f(char *str1, char *str2) { //while( *str1++ != 'a' ) would work, str2 is the problem while( *str1 != '\0') { *str2++ = *str1++ ; } } int main() { char* string1="test"; char string2[256]; f(string1, string2); printf("%s", string2); return 0; } Ultima modifica di airon : 14-11-2013 alle 15:52. |
![]() |
![]() |
![]() |
#3 |
Senior Member
Iscritto dal: Mar 2003
Città: Rimini
Messaggi: 1843
|
Purtroppo devo mantenere la stessa struttura, non posso cambiare la funzione se non per correggere il problema che causa il crash.
Non ho ancora capito dove sia il problema, per ora la mia idea è questa: str1 dentro la funzione memorizza l'indirizzo della prima lettera della stringa in memoria, questa potrebbe essere diciamo all'indirizzo 5000. str1++ mi manda all'indirizzo seguente, diciamo 5002 e dunque facendo *str1++ ottengo la seconda lettera e così via. str2 dentro la funzione memorizza l'indirizzo della prima lettera in string2, supponiamo all'indirizzo 2000. Facendo str2++ dovrei (credo) andare all'indirizzo 2002 (mi sto sempre inventando i numeri) ed accedere al secondo elemento dell'array. Questo però sembra non essere vero. |
![]() |
![]() |
![]() |
#4 |
Senior Member
Iscritto dal: Feb 2004
Città: milano
Messaggi: 2148
|
Eh ma scusa il while ha dentro:
*str++ = *str2++ (a parte che deve essere str1) Tu stai associando a str1 quello che trovi in str2. str1 ha 4 caratteri str2 ne ha 256 Come puoi mettere dentro str1 256 caratteri? E' un puntatore ad una stringa che in memoria, in fase di compilazione ha 4 spazi non 256. Se inverti i due puntatori ovvimaente ti va ma copi str1 in 2 come da logica dovrebbe essere ![]() Ultima modifica di airon : 14-11-2013 alle 16:02. |
![]() |
![]() |
![]() |
#5 | |
Senior Member
Iscritto dal: Mar 2003
Città: Rimini
Messaggi: 1843
|
Quote:
Temo di dover spiegare anche questo. |
|
![]() |
![]() |
![]() |
#6 |
Senior Member
Iscritto dal: Nov 2013
Città: Nel cuore dell'8 Mile di Detroit
Messaggi: 3737
|
beh è ovvio, nel ciclo devi controllare il finestringa
|
![]() |
![]() |
![]() |
#7 |
Senior Member
Iscritto dal: Nov 2013
Città: Nel cuore dell'8 Mile di Detroit
Messaggi: 3737
|
anche
è vero è vero è vero.... dovrebbe dare errore cosi' ma perché non dichiara direttamente le string ?? |
![]() |
![]() |
![]() |
#8 |
Senior Member
Iscritto dal: Feb 2004
Città: milano
Messaggi: 2148
|
Scusate ma io ricordo che è solo in C che la definizione del puntatore è implicitamente const (anche se si omette è solo read only quindi non si può cambiare direttamente il valore).
E' così anche in C++ o faccio confusione? |
![]() |
![]() |
![]() |
#9 |
Senior Member
Iscritto dal: Mar 2003
Città: Rimini
Messaggi: 1843
|
Quindi non c'è nessun modo possibile per far funzionare la funzione lasciando la dichiarazione di string2 così come è nel main?
|
![]() |
![]() |
![]() |
#10 | |
Senior Member
Iscritto dal: Mar 2003
Città: Rimini
Messaggi: 1843
|
Quote:
char string1[]="test"; char string2[256]; il ciclo while è infinito e crasha per questo motivo. Ho bisogno di mettere un paio di punti fermi: 1) char *string1="test"; char string2[256]; f(string1, string2); passa alla funzione f l'indirizzo contenuto in string1 (indirizzo del char 't' di 'test') e l'indirizzo del primo char di string2. 2) *str1++ nella funzione f sta eseguendo prima il ++ spostandosi al carattere successivo nella stringa e poi il dereference per prendere il valore contenuto a quell'indirizzo. Allo stesso modo *str2++ si sta spostando all'indirizzo successivo dell'array prendendone il contenuto con *. Sono corrette queste due affermazioni o c'è qualcosa che non so o che so in modo sbagliato? |
|
![]() |
![]() |
![]() |
#11 |
Senior Member
Iscritto dal: Sep 2005
Città: Torino
Messaggi: 606
|
la difficoltà del c sta tutta qua e nel decadimento degli array a puntatori.
__________________
"Se proprio dovete piratare un prodotto, preferiamo che sia il nostro piuttosto che quello di qualcun altro." [Jeff Raikes] "Pirating software? Choose Microsoft!" |
![]() |
![]() |
![]() |
#12 |
Senior Member
Iscritto dal: Feb 2004
Città: milano
Messaggi: 2148
|
Rieccomi,
allora ho fatto un po' di confusione ![]() char *p = "stringa"; che io sappia è un'istruzione valida (almeno in C) p è un puntatore (e quindi contiene l'indirizzo di memoria della stringa "stringa"). Non posso variarne il contenuto. se io stampo *p mi stampa "stringa". Non posso però cambiare i caratteri di "stringa". Ed è questo l'errore del programma. Posso volendo cambiare l'indirizzo a cui punta p facendo: p = "nuova stringa". Se stampo di nuovo *p esce "nuova stringa", se stampo p stampo l'indirizzo in memoria di "nuova stringa". Giusto no? ![]() Ultima modifica di airon : 14-11-2013 alle 19:53. |
![]() |
![]() |
![]() |
#13 | |
Senior Member
Iscritto dal: Jan 2012
Messaggi: 1267
|
Quote:
char string1[] = "test"; equivale a char* const string1 = "test\0"; ? Son sicuro che l'array è un puntatore const, ma non ricordo se assegnare una literal ad un puntatore char non aggiunge il terminatore implicitamente. |
|
![]() |
![]() |
![]() |
#14 |
Senior Member
Iscritto dal: Nov 2013
Città: Nel cuore dell'8 Mile di Detroit
Messaggi: 3737
|
il fatto è che una volta che hai dichiarato char*="qualcosa"
non puoi più variarlo, sovrascriverlo, allungare il vettore puoi solo spostare il cursore * avanti e indietro dentro la stringa non puoi pertanto fare riassegnazioni a quell'array la dichiarazione char[] teoricamente uguale formalmente è diversa vale anche per records strutturati |
![]() |
![]() |
![]() |
#15 |
Senior Member
Iscritto dal: Sep 2005
Città: Torino
Messaggi: 606
|
![]()
__________________
"Se proprio dovete piratare un prodotto, preferiamo che sia il nostro piuttosto che quello di qualcun altro." [Jeff Raikes] "Pirating software? Choose Microsoft!" |
![]() |
![]() |
![]() |
#16 | |
Senior Member
Iscritto dal: Mar 2003
Città: Rimini
Messaggi: 1843
|
Quote:
Non sapevo che la dichiarazione char *p = "test" poi non permettesse più di modificare il contenuto di p. Purtroppo ho un'altra domanda ![]() Invertendo str1 e str2 e risolvendo dunque l'esercizio, perchè il ciclo while si ferma quando incontra il \0 di fine stringa? |
|
![]() |
![]() |
![]() |
#17 | |
Senior Member
Iscritto dal: Sep 2005
Città: Torino
Messaggi: 606
|
Quote:
__________________
"Se proprio dovete piratare un prodotto, preferiamo che sia il nostro piuttosto che quello di qualcun altro." [Jeff Raikes] "Pirating software? Choose Microsoft!" |
|
![]() |
![]() |
![]() |
#18 | |||
Member
Iscritto dal: Nov 2012
Messaggi: 126
|
Quote:
In effetti, sorprende sempre molti scoprire che lo standard non la contiene nemmeno la parola "stack". Quote:
"Some compilers have a switch controlling whether string literals are writable or not (for compiling old code), and some may have options to cause string literals to be formally treated as arrays of const char (for better error catching)." http://c-faq.com/decl/strlitinit.html Interessanti questioni architetturali a parte, per cavarsela sempre e comunque ricordiamo che basta agire seguendo: https://www.securecoding.cert.org/co...tring+literals Quote:
Il tutto senza voler essere pedante ma solo per ricordare quanto la programmazione di sistema sia vasta, affascinante e ... possa causare parecchi incubi! |
|||
![]() |
![]() |
![]() |
Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 22:26.