Pages: 1 [2]   Go Down
Author Topic: Task leOS, strano problema.  (Read 1063 times)
0 Members and 1 Guest are viewing this topic.
MC
Offline Offline
God Member
*****
Karma: 14
Posts: 917
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset


....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!
Logged

Vi è una spiegazione scientifica a tutto.
La fede è solo quell'anello che si porta al dito dopo il matrimonio.

Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 325
Posts: 22498
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Uh, è vero. E' un array.
Logged


0
Offline Offline
Shannon Member
****
Karma: 130
Posts: 10454
:(){:|:&};:
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
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.
« Last Edit: October 25, 2012, 08:58:49 am by lesto » Logged

sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

MC
Offline Offline
God Member
*****
Karma: 14
Posts: 917
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:

#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:

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
« Last Edit: October 25, 2012, 09:28:38 am by niki77 » Logged

Vi è una spiegazione scientifica a tutto.
La fede è solo quell'anello che si porta al dito dopo il matrimonio.

0
Offline Offline
Shannon Member
****
Karma: 130
Posts: 10454
:(){:|:&};:
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
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)
Logged

sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

MC
Offline Offline
God Member
*****
Karma: 14
Posts: 917
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Sono un pò perplesso dal discorso del sizeof, anche se ha estremamente senso quello che dici, che diamine di tipo di dato è per occupare 5byte??????
Non è che 1byte è il tipo e 4 byte l'indirizzo?
Logged

Vi è una spiegazione scientifica a tutto.
La fede è solo quell'anello che si porta al dito dopo il matrimonio.

0
Offline Offline
Shannon Member
****
Karma: 130
Posts: 10454
:(){:|:&};:
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

devo rimangiarmi ciò che ho detto su sizeof:

Quote
When sizeof is applied to the name of an array, the result is the size in bytes of the whole array. (This is one of the few exceptions to the rule that the name of an array is converted to a pointer to the first element of the array.) The following program uses sizeof to determine the size of a declared array, avoiding a buffer overflow when copying characters

se ripenso alle centinaia di righe di codice inutili...  smiley-cry
Logged

sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

MC
Offline Offline
God Member
*****
Karma: 14
Posts: 917
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

é si, del resto bastava aggiungere elementi alla char[] per vedere che il valore aumentava !!!

Code:

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


ritorna:

testo: 12345678
length: 9
length of ptr: 4


il puntatore è 4 byte , infatti ora mi torna!!!

SO TROPPO IL MIGLIORE!!!  smiley-lol
Logged

Vi è una spiegazione scientifica a tutto.
La fede è solo quell'anello che si porta al dito dopo il matrimonio.

0
Offline Offline
Shannon Member
****
Karma: 130
Posts: 10454
:(){:|:&};:
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

+1
Logged

sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

MC
Offline Offline
God Member
*****
Karma: 14
Posts: 917
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Contraccambio (+1) per premiare lo spirito di sano confronto che si è instaurato!
Logged

Vi è una spiegazione scientifica a tutto.
La fede è solo quell'anello che si porta al dito dopo il matrimonio.

Pages: 1 [2]   Go Up
Jump to: