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