Newsgroup: it.comp.lang.c
Titolo: allocare memoria per una struct  in una funzione

salve,
dovrei costruire un vettore di strutture di tipo keyType all'interno di 
una funzione.
quella che segue è il mio modesto tentativo, naturalmente non 
funzionante, credo che dovrei usare un puntatore a puntatore (quindi int 
leggiKey(char *nomefile,keyType **vetKeys) ), ma mi sto perdendo tra gli 
operatori * e &, potreste farmi capire come fare??
il codice seguente inoltre crea e rimpie il vettore tranne che nel primo 
elemento (cioè vetKey[0].nomeKey è sballato mentre i successivi no...) 
anche questo mi risulta strano...
grazie anticipatamente per la pazienza
gx
struct tipo_key{
	char *nomeKey;
	int nImg;
};
typedef struct tipo_key keyType;
int leggiKey(char *nomefile,keyType *vetKeys){
	FILE *inputFile;
	char c;
	char *parola;
	int i,k=0;
	if((inputFile=fopen(nomefile,"r+"))==NULL){
		perror("apertura file");
		exit(1);
	}
	while((c=getc(inputFile))!=EOF){
		i=0;
		parola=NULL;
   		while(isalpha(c)){
			if((parola=realloc(parola,i+1))==NULL){
				perror("allocazione nuovo char");
				exit(1);
			}
			parola[i]=c;
			c=getc(inputFile);
			i++;
		}
		parola[i]='\0';
		if((*(&vetKey+k)=malloc(sizeof(keyType)))==NULL){
			perror("allocazione nuova struttura");
			exit(1);
		}
	if((vetKey[k].nomeKey=malloc(sizeof(char)*(i+1)))==NULL){
			perror("allocazione nuova stringa");
			exit(1);
		}
		strcpy(vetKey[k].nomeKey,parola);
		free(parola);
		k++;
	}
	return k;
}

 typedef struct tipo_key keyType;
keyType pippo[100];
e la funzione che riceve keyType *pippo
*pippo+1 vale pippo[1]
Ciao


forse non mi sono fatto capire...
il vettore di strutture lo vorrei creare dinamicamente, non sapendo a 
priori di quanti elementi debba essere composto.
per questo nella funzione che ho proposto c'è tutto quel uso di malloc e 
realloc...
la mia domanda è dunque: come fare per allocare memoria per il mio 
vettore dall'interno della funzione (sempre se è possibile)?
gx

beh se vuoi fare una cosa senza malloc puoi fare un array di puntatori a 
strutture e ogni volta che dichiari una struttura metti il puntatore 
dentro l'array no?

LinuxMan wrote:

senza malloc? e la memoria per contenere le strutture come la riservo? 
però l'idea di costruire un vettore di puntatori a struct invece che un 
vettore di struct potrebbe essere buona...
per costruirlo lo dichiaro:
keyType *key;
e lo costruisco:
*(&key+i)=malloc(sizeof(keyType));
dove i è un indice incrementale...
giusto? e lo posso fare all'interno di una funzione? cioè se passo key 
come dichiarato su, alla funzione, all'uscita da questa avrò il vettore 
allocato?
gx

 }
Vedi se cosi' cambia qualcosa.
Ciao,
Ema

 dove i è un indice incrementale...
+ semplice
keyType *key[255];
int i;
e poi quando vuoi fai
keyType keyalloc;
key[i] = keyalloc;
i++;
dovrebbe funzionare no?

A scanso di errori e/o distrazioni che sicuramente c'ho messo nel post
precedente, ecco un codicillo che funzia:
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
typedef struct tipo_key{
  char * nomeKey;
  int nImg;
} keyType;
int leggiKey(char * nomefile,keyType * * vetKey){
  FILE *inputFile;
  char c, *parola;
  int i, k=0;
  *vetKey = NULL;
  if((inputFile=fopen(nomefile,"r+"))==NULL){
    perror("apertura file");
    exit(1);
  }
  while((c=getc(inputFile))!=EOF){
    i=0;
    parola=NULL;
    while(isalpha(c)){
      if((parola=realloc(parola,i+1))==NULL){
        perror("allocazione nuovo char");
        exit(1);
      }
      parola[i]=c;
      c=getc(inputFile);
      i++;
    }
    if((parola=realloc(parola,i+1))==NULL){
      perror("allocazione nuovo char");
      exit(1);
    }
    parola[i]='\0';
    if(((*vetKey) = realloc((*vetKey), (k+1) * sizeof(keyType)))==NULL){
      perror("allocazione nuova struttura");
      exit(1);
    }
    if(((*vetKey)[k].nomeKey = malloc(sizeof(char)*(i+1)))==NULL){
      perror("allocazione nuova stringa");
      exit(1);
    }
    strcpy((*vetKey)[k].nomeKey, parola);
    free(parola);
    k++;
  }
  return k;
}
int main(void) {
  int i,k;
  keyType * chiavi;
  k = leggiKey("prova.txt", &chiavi);
  for (i=0; i<k; ++i)
    printf("%d)--> <%s>\n",i,chiavi[i].nomeKey);
  return 0;
}
Ciao,
Ema

 
e no.. questa realloc mi manda in segmentazione.

 e no.. questa realloc mi manda in segmentazione.
Vedi sopra il codicillo.
Non avevo inizializzato *vetKey = NULL...
Per questo e forse altro ho messaggiato di nuovo...
Ciao,
Ema

Ema wrote:

grazie funziona alla grande, e anche oggi ho imparato qlc di nuovo ^^

 dovrebbe funzionare no?
No. Prima di tutto nell'assegnazione sono coinvolti 2 tipi incompatibili
(keyType* e keyType). Anche scrivendo:
keyType keyalloc;
key[i] = &keyalloc;
Non risolvi il problema perche` keyalloc e` allocato in modo automatico
e all'uscita dalla funzione in cui e` dichiarato viene deallocato. Il
puntatore che hai memorizzato, quindi, non e` riutilizzabile.
Luca
-- 
Home: 
http://kronoz.cjb.net
Una donna sposa un uomo sperando che cambi, e lui non cambiera`. Un
uomo sposa una donna sperando che non cambi, e lei cambiera`.

 Luca
Non avevo letto che gli serviva tenerlo in memoria. Certe volte devo 
leggere meglio