Go Down

Topic: Task leOS, strano problema. (Read 1 time) previous topic - next topic

niki77



....una stringa char è composta ...



A parte il fatto che non è una stringa ma un array di char , l'array di char non dovrebbe avere terminatore!
Vi è una spiegazione scientifica a tutto.
La fede è solo quell'anello che si porta al dito dopo il matrimonio.

leo72


lesto

#17
Oct 25, 2012, 03:55 pm Last Edit: Oct 25, 2012, 03:58 pm by lesto Reason: 1
no, il SO non si incazza se sfori un array, ma se sfori in un area di memoria non dedicata al tuo programma (il SO ti da un bel blocco all'inizio, per evitare che tu gli rompa le balle spesso)

io credo che l'errore sia quì racchiuso:
Code: [Select]

printf("Riga A: %c \n" , testo[contatore]);
printf("Riga B: %c \n" , testo[contatore+1]);

abbiamo conatore che va da 0 a 3 (giusto), ma la riga B la andiamo a prendere dall'elemento conatatore+1, quindi di fatto usiamo il range da 1 a 4 (sbagliato)

ora, se ci va di culo e dalla locazione di memoria 4 in poi troviamo relativamente presto uno \0 visualizziamo garbage. Ora, è poco probabile trovare uno \0 lì per caso, considerando che abbiamo un range di 256 valori (probabilità di 1/256). quindi probabilmente in un atmega sfondi la ram e chissà cosa succede.

Su un PC, oltre ad avere un sacco di ram in più (non parlo della ram totale, ma di quella assegnata al programma), hai anche il controllo del SO, quindi se nella ram assegnata non trovi lo \0 ci pensa il SO a mandarti in crash.

@niki77 & leo: gli array di char sono dette stringhe, da non confondere con le String che invece sono un oggetto. per riprova, esiste una libreria ansi C, la string.h, che lavora sugli array di char.
e no, gli array di char SONO terminati a \0. Anche la classe Stringa al suo interni usa un array di char terminato con \0. solo che non te lo fa vedere.
sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

niki77

#18
Oct 25, 2012, 04:23 pm Last Edit: Oct 25, 2012, 04:28 pm by niki77 Reason: 1
Si, mi sa che ha ragione lesto...
O meglio, non lo so, ma ho scritto due righe di codice che danno un risultato interessante...

Code: [Select]


#include <stdio.h>

int main()
{
   char testo[] = "1234";
char testo1[] = "1234";

char * ptr = testo;
char * ptr1 = testo1;

ptr+=4;

*ptr = 'A';

printf("testo: %s \n", testo);

ptr1+=5;

*ptr1 = 'A';

   printf("testo1: %s \n", testo1);

getchar();


}



il risultato a schermo è il seguente :

testo: 1234A> "
testo1: 1234

Questo non mi garantisce che il compilatore riservi in coda a testo e testo1 un \0  , ma mi garantisce che printf e surrogati quando si chiede la rappresentazione stringa di un char[] la ritiene terminata con il \0
Nel primo esempio avendo fatto una manovra catso modificando a mano l'indirizzo del puntatore ho praticamente sovrascritto il teorico \0 facendo si che richiedendo poi la visualizzazione a schermo di quella variabile in formato stringa , essa non si sia limitata a 1234 come da dichiarazione, e nemmeno ad 1234A , ma bensi si sia spinta fino a trovare nuovamente un \0

:smiley-roll:
P.S. sto cominciando a nutrire dubbi sull'utilità di questi esperimenti  :smiley-yell:


RI P.S. ora ho la certezza che dichiarando un char[] in quella maniera viene riservato il \0 in coda:

Code: [Select]


int main()
{
   char testo[] = "1234";

printf("testo: %s \n", testo);
printf("length: %u \n", sizeof(testo));

getchar();


}



Per l'utilità dei test ho ancora dubbi ...  :smiley-sad-blue:
Vi è una spiegazione scientifica a tutto.
La fede è solo quell'anello che si porta al dito dopo il matrimonio.

lesto

quando usi " " il compilatore aggiunge sempre /0 riservando il giusto spazio.

ciò non avviene con lo ' ', che però non salva una stringa ma un carattere solo (se ci metti più caratteri CREDO che li sommi)

quindi il test 1 potevi farlo anche:
Code: [Select]

char testo3[4];
char prova4 = 'p'; //se siamo fortunati prova4 si trova nella ram subito dopo test3, quindi possiamo verificare l'overflow!

println("%c\n", prova4 );

testo3[0] = '1';
testo3[1] = '2';
testo3[2] = '3';
testo3[3] = '4';
//andiamo un pò nel regno dell'overflow
testo3[4] = '0';

println("%c\n", prova4 ); //venghino siori e siore, prova4 modificata senza trucco e senza inganno!

testo3[10] = '\0';//assicuriamoci di non andare in overflow di ram va.. forziamo il tappo a 10 caratteri

println("%s", testo3); //quì stampa 1234 e del garbage! se la ram èp stata assegnata contigua, il primo carattere di garbage è prova4!

il secondo test invece non ha senso; sizeof(testo) ti ritorna il numero di byte usati dal PUNTATORE testo, non la dimensione della stringa / array; in c non esiste alcun metodo per conoscere la dimensione di un array, a meno che te stesso non ne tenga conto o con un contatore, o con un carattere di tappo (tipo \0)
sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

Go Up