Newsgroup: it.comp.lang.c
Titolo: Accesso a membri struttura

Salve,
vorrei un aiuto su come accedere a un membro di una struttura (o meglio a un
membro di una struttura dichiarara come puntatore). Grazie in anticipo !!!
Ho fatto questo esempio per spiegarmi meglio:
typedef struct {
    int uno;
    int due;
} struttura_1;
typedef struct
{
  char nome[254 + 1];
  struttura_1 in;
} struttura_2;
struttura_2* prova(char r[]);
struttura_2* prova(char r[])
{
	struttura_2* struttura;
	char nome_funzione[]="Ciao";
	int uno_funzione;
	int due_funzione;
	/* vorrei copiare 'nome_funzione' nel membro 'nome' della struttura
'struttura_2' */
	/* analogamente vorrei compiare 'uno_funzione' e 'due_funzione' , es: */
	struttura->in->uno=uno_funzione; /* NON FUNGE */
 
	/* COME FARE ? */
	return(struttura);
}
void main()
{
	struttura_2* struttura;
	char vettore_r[100];
	struttura=prova(vettore_r);
}
--------------------------------
Inviato via 
http://arianna.libero.it/usenet/





 Inviato via 
http://arianna.libero.it/usenet/
Benvenuto nel mondo dei puntatori 8pppp
Un saluto a tutti && un augurio per un ottimo 2010!
-- 
-- Giacometti Luca alias Samel "Close the world,txen eht nepo!" "You
will never break my mind!"
--- news://
freenews.netfront.net/
 - complaints: 
ne...@netfront.net
 ---

Grazie mille per l'aiuto ! Davvero ! Stavo appunto per seguire questa
strada, ma non ero
sicuro.
Una cosa... adesso compila senza problemi, però ottengo un errore di
'segmentation fault' in esecuzione... Dipende
dal fatto che ho dichiarato un puntatore a una struttura, senza allocare la
memoria ???
struttura_2* prova(char r[])
{
	struttura_2* struttura; /* qui è solo un puntatore quindi riserv solo 4
byte in memoria (supponendo un sistema a 32 bit) */
 
 	char nome_funzione[]="Ciao";
 
 	int uno_funzione;
 	int due_funzione;
        struttura=(struttura_2 *)malloc(sizeof(struttura_2)); /* così va bene ???
*/
        strcpy(struttura2->nome,nome_funzione);
}
... mentre se dichiarassi così la struttura :
struttura_2 struttra;
avrei anche lo spazio allocato staticamente giusto ? Però nel mio caso,
visto che la funzione deve tornare
un puntatore, devo allocare dinamicamente la memoria e poi tornare un
puntatore...
GRAZIE ancora !


 Inviato via 
http://arianna.libero.it/usenet/
-- 
Giacometti Luca alias Samel - "Close the world,txen eht nepo!" - "You


         struttura=(struttura_2 *)malloc(sizeof(struttura_2));
Via il cast:
struttura=malloc(sizeof(struttura_2));
-- 
questo articolo e` stato inviato via web dal servizio gratuito 
http://www.newsland.it/news
 segnala gli abusi ad 
ab...@newsland.it


Visto che stiamo facendo i pignoli:
struttura = malloc(sizeof(*struttura));

 struttura = malloc(sizeof(*struttura));
Questa non mi piace molto. sSlitamente faccio il sizeof solo su tipi,
non su dati.
In questo caso e' ancora peggio pero' 8pppp che perversione! 


 non su dati.
A parte che il sizeof � lecito sia sui tipi che sui dati, quell'istruzione
� la cosa pi� sicura da fare, se si vuol prescindere dal tipo del
puntatore per il quale allocare memoria.



<OT>
Apro una piccola parentesi che spero possa essere utile a chi non è
molto in confidenza con il mondo GNU e quello che s'intende per
"portabilità" in questo mondo (ovviamente non s'intende la portabilità
in senso puro, ma una variazione sul tema che sembra essere abbastanza
condivisa tra gli sviluppatori - in generale scrivere in c89 o c99
puro con funzioni ANSI o POSIX pure è considerato _non_ portabile, a
causa di mancanze e omissioni di compilatori e sistemi operativi).
Il problema effettivo potrebbe nascere se decidi di voler far
compilare senza errori nè warning sia in C che in C++, oppure su vari
compilatori con vari switch in command line.
Per essere sicuri di non sbagliare tipo di dato quando allochi (non
perché sei stupido, ma semplicemente perché cambi tipo di dati alle
variabili, magari neanche a mano ma con un refactor o un find/
replace), puoi segliere molte strade:
in C:
var = malloc(sizeof(*var));  /* questa è in generale la più comoda/
sicura su tutti i compilatori C */
alla C++:
var = (tipo*)malloc(sizeof(tipo));  /* <-- il compilatore ti avverte
se "var" non è di tipo "tipo*" */
e quindi più comodamente con una macro:
#define ALLOCA(_TIPO) ((_TIPO*)malloc(sizeof((_TIPO)))
var = ALLOCA(tipo); /*<-- come sopra, ma scrivi meno e non scordi il
cast */
se ti senti estremamente "perverso" (come dice te) in c++ puoi anche
usare l'operatore typeof() del gcc rinunciando alla portabilità (per
il software GNU il gcc è praticamente il _solo_ compilatore)
#define ALLOCA(_VAR) do { (_VAR) = (typeof((_VAR)))malloc(sizeof(*
(_VAR))); }   while(0)
ALLOCA(var);
come vedi puoi complicare a piacimento la situazione. In pratica, cosa
si fa in generale sui programmi che devono essere sia portabili che
compilabili anche in c++? La via scelta dalla maggior parte dei
programmi GNU (giusta o sbagliata che sia), è semplicemente quella di
non usare malloc, ma una macro che chiami come vuoi (diciamo
my_malloc, per semplicità, di solito si usa prependere una 'x' alla
funzione standard di cui fai il wrap, quindi xmalloc, xfree, xstrdup,
etc.) che definisci un po' come vuoi.
Fare il wrapping delle funzioni di allocazione della memoria (quindi
malloc/calloc/realloc/free, sia con macro che con funzioni solitamente
definite inline) porta numerosissimi altri vantaggi oltre alla
"scemenza" sintattica di cui sopra, tra i quali la possibilità di
avere degli agganci software per monitorare le allocazioni/
deallocazioni (e quindi avere il monitoraggio completo e real-time
della gestione della memoria anche banalmente inserendo una printf),
poter scovare facilmente memory leaks senza ricorrere a strumenti
esterni, e infine lasciarti la possibilità di sostituire il gestore di
memoria del sistema con un gestore di terze parti (che so, un hoard
allocator o direttamente uno custom) senza dover cambiare il codice
del progetto.
</OT>
Scusate l'OT ma credo che, data la fantasia intrinseca che l'open
source esprime anche sulle piccole cose, sia interessante ogni tanto
citare le soluzioni più famose che mette a disposizione! :-)
Ciao!

 source esprime anche sulle piccole cose
Onestamente non credo che sia una fantasia specifica del mondo open
source. Cio�, la programmazione condizionale � studiata apposta per
attivare diversi percorsi di compilazione a seconda dei casi. Le tecniche
che descrivi verrebbero naturali a chiunque programmi in C/C++, nel caso
abbia quel tipo di necessit�. La questione, pi� che altro, secondo me, �
che � difficile scrivere un'applicazione che debba, comunque e sempre,
essere compilata sia da un compilatore C che da uno C++. La scelta di un -
ed un solo - linguaggio � fondamentale: o si sviluppa in C, o si sviluppa
in C++.



Magari. Penso chiunque, se potesse scegliere, utilizzerebbe solo un
linguaggio. Purtroppo in progetti medio/grossi succede che 1)
l'utilizzo di librerie di terze parti è indispensabile e 2) l'utilizzo
di un linguaggio specifico è migliore per lo sviluppo di uno specifico
sottoinsieme dell'implementazione.
Dove lavoro adesso abbiamo un tree di dimensioni vicine al GB (eh sì,
e levando documenti e file sparsi arriveremo a più di 700Mb di codice)
di progetti scritti in C, MDL (un linguaggio C-like proprietario), C+
+, C++/CLI, C#, PL-SQL, e altre varie amenità. Logicamente le librerie
di calcolo matematico e il codice "datato" sono in C (parti della
prima versione del software, che avrà più di dieci anni, ancora sono
funzionanti!), mentre le interfaccie utente sono in C#, e vari
progetti sono scritti in C++ per facilitare il riutilizzo degli
oggetti.
Non nascondo che una buonissima percentuale del tempo di sviluppo è
persa durante l'integrazione di programmi e librerie, ma purtroppo non
ci sono altre soluzioni (economicamente) accettabili se non fare
strani "magheggi" nel codice. :-(
Meglio neanche parlare della difficolta di interazione tra codice che
gira su virtual machine (.NET e Java) e codice un-managed (C e C++)
che solo a pensarci passo un brutto capodanno! :-D
Ciao - e ancora auguri!

 source esprime anche sulle piccole cose
Onestamente non credo che sia una fantasia specifica del mondo open
source. Cio�, la programmazione condizionale � studiata apposta per
attivare diversi percorsi di compilazione a seconda dei casi. Le tecniche
che descrivi verrebbero naturali a chiunque programmi in C/C++, nel caso
abbia quel tipo di necessit�. La questione, pi� che altro, secondo me, �
che � difficile scrivere un'applicazione che debba, comunque e sempre,
essere compilata sia da un compilatore C che da uno C++. La scelta di un -
ed un solo - linguaggio � fondamentale: o si sviluppa in C, o si sviluppa
in C++.
-- 


 linguaggio.
Non sto dicendo questo e sui "progetti medio/grossi" ci lavoro anch'io.
Quel che sto dicendo � che se si sceglie di sviluppare un modulo software
utilizzando un linguaggio, quello � il linguaggio scelto. Punto. Se si
sceglie di sviluppare in C, si sviluppa in C; idem per C++. Che poi pi�
moduli software, scritti in linguaggi differenti, vadano a comporre un
progetto intero lo so bene anch'io, ma, appunto, � un altro discorso.
