Newsgroup: it.comp.lang.c
Titolo: problema con un algoritmo

mi date una mano a capire dove sbaglio?
Compilando il seguente codice non viene emesso nessun errore o warning da
parte del comp. sia con vc++6 che con gcc e con turbo c ++ però quando provo
a lanciare il programma appare un mess di errore ;
Il programma altro non è che un ipotetico algoritmo di ordinamento
alfabetico :
vi dirò di + debuggando e vedendo il codice disassemblato tutto sembra
portare alla riga cui codice è  *a[z]=0;  essenzialmente il programma dopo
aver trovato il valore + grande di codice ASCII, che possono andare nel mio
esempio  da 97 a 122  ( a - z minuscole) , lo azzera cosicchè al prossimo
ciclo trova quello subito sotto il primo , il fatto è che l'azzeramento
avviene tramite puntatore a puntatore o array di puntatore che dir si
voglia, il codice che qui riportato usa il metodo degli array di puntatori
ma
vi assicuro che anche con i puntatori a puntatori mi dà lo stesso errore.
E' come se attraverso una funzione non si può accedere ad un elemento del
segmento dati utilizzando un doppio rinvio; per essere + precisi è come se
dopo la chiamata alla funzione i dati vengano messi nel segmento codice e
quindi non + modificabili .Ecco il codice:
----------------------------------------------------------
#include <stdio.h>
void ordina(char *a[],char *b[]);
int main(void)
{
 char *m[4]={"uno","due","tre","zero"};
 char *n[4];
    int l;
 ordina(m,n);
 for(l=0;l<4;l++)
 {
 puts(n[l]);
 }
 return 0;
}
void ordina(char *a[],char *b[])
{
 int i,z,k;
 char m=0;
 for(k=4;k>0;k--)
 {
  for(i=0;i<4;i++)
  {
   if(*a[i]>m)
   {
    m=*a[i];
    z=i;
   }
  }
  b[k]=a[z];
  *a[z]=0;  /* presunto errore*/
 }
}
ringrazio anticipatamente.
P.S.:
La cosa + strana è che il confronto numerico tra *a[i] ed m lo esegue
correttamente nel senso che la funzione vede quello che c'è dentro *a[i] ma
dopo, poche righe + sotto non riesce ad accedervi .
Il mess dopo debug è :
First-chance exception in 1.exe: 0xC0000005: Access Violation.

l´array di puntatori a char *m4 e´ costituito da puntatori a caratteri che
sono stati messi in rom, poiche´ hai inizializzato il tutto in modo statico.
In parole povere passando il puntatore a quelle stringhe non le rende
modificabili.
Avresti dovuto allocare dinamicamente spazio per le stringhe di m4 e poi
fare delle strcpy con "uno", "due", ecc...allora sarebbero stati
modificabili poiche´ a quel punto le avevi messe in ram e cioe´ nello heap.
Per cui hai l´errore di access violation perche´stai provando a modificare
il contenuto di un indirizzo di una zona di memoria a sola lettura.

 wrote in message
8ji8uk$9dq$1...@newstoo.ericsson.se...

 Alla stregua delle mie conoscenze si ha che:
 Il segmento codice ossia quello che tu hai  chiamato rom (read only memory)
contiene le istruzioni del programma e le costanti usate dal programma, per
ragioni storiche quest' area è anche chiamata segmento TEXT. I dati inseriti
in questo segmento non variano mai e sui sistemi UNIX l'intero segmento è
definito come segmento di sola lettura.
Al contrario il segmento data contiene tutte le variabili permanenti
inizializzate, cioè le variabili globali e static inizializzate;( e possono
quindi essere modificate)
Ora, visto e assodato il messaggio che mi appare , come mai il : char
*m[4]={"uno","due","tre","zero"}; viene messo nel CS (code segment) invece
che nel DS (data segment) ??
Ciao e grazie ancora.

 grep -A7 ^\`-fw
`-fwritable-strings'
     Store string constants in the writable data segment and don't
     uniquize them.  This is for compatibility with old programs which
     assume they can write into string constants.  The option
     `-traditional' also has this effect.
     Writing into string constants is a very bad idea; "constants"
     should be constant.
[root@fokhouse /root]#
Ciao ciao,
Andrea
-- 
"...Unix, MS-DOS, and Windows NT (also known as the Good, the Bad, and 
 the Ugly)."
(by Matt Welsh)


comunque avevi ragione in quell'altro modo funziona , mi dai una mano a
capire perchč se sposto la dichiarazione di int l di due rughe sotto mi dice
che l non č stato definito?cioč se scrivo cosě non va bene :
ordina(m,n);
int l;
for(l=0;l<4;l++)
perchč???

 perchè???
In C (standard 1989 e versioni precedenti) tutte le dichiarazioni
devono essere all'inizio del blocco; il compilatore avrebbe dunque
dovuto segnalare come errore la "int l;" che NON si trova, appunto,
a inizio blocco, bensi` dopo uno o piu` statement.
Per potere "dichiarare dove serve", devi usare invece C++ ovvero
(se ne trovi...) compilatori C che implementino il nuovo standard
C (non ancora ufficialmente approvato, informalmente detto "C9X"),
che ha mutuato dal C++ parecchie cose fra cui la liberta` nel
piazzare le dichiarazioni.
Alex

 C (non ancora ufficialmente approvato, informalmente detto "C9X"),
Ma non era già stato approvato?
EMG

 Ma non era gią stato approvato?
Puo` darsi, mi sara` sfuggito il voto ufficiale ISO di approvazione
(credevo fosse schedulato per l'autunno venturo...?).
Alex


"...the night was heavy and the air was alive..."
http://www.poli.studenti.to.it/~s93146/

 Non so se ho detto una cavolata...
No, ci sei vicino, ma e` importante ricordarsi che si possono
avere dichiarazioni "piu` annidate" di quelle che valgono per
l'intera funzione, ponendole entro un blocco annidato.
Alex

 }
Ciao
-- 
Pietro F. Maggi                             pietromaggi AT libero DOT it
http://pietromaggi.50megs.com/
 
La pedina è il pezzo più importante degli scacchi...per la pedina

si è vero ma il problema dei dati messi nel CS rimane lo stesso, anche se
alla fine penso di aver capito