PDA

View Full Version : [C] Realloc: Segmentation Fault


Starise
03-11-2006, 09:46
Ragazzi, ho un grave problema, sicuramente facile da identificare, ma io non ci riesco! Un programma che sto scrivendo mi va in seg.fault!

L'allocazione avviene tramite questa funzione:
int Alloca_Memoria( CONTATTI **Ptr, int dim )
{
CONTATTI *Nuovo_Ptr = NULL; /* nuovo puntatore... */
/* ...che contiene il risultato della chiamata a realloc */
Nuovo_Ptr = ( CONTATTI * )realloc( *Ptr, dim * sizeof( CONTATTI ) );

if( Nuovo_Ptr == NULL )
{
/* realloc restituendo NULL ci avvisa che non c'e' memoria disponibile
* per allocare lo spazio richiesto */
return (0);
}
else
{
/* l'allocazione ha avuto successo e si utilizza il nuovo indirizzo
* di memoria che contiene lo spazio necessario */
Pausa();
*Ptr = Nuovo_Ptr;
return (1);
}
}

Quando ci vado a scrivere:

void Aggiungi_Contatto( CONTATTI **Rubrica, int *num_contatti )
{
/* per lavorare sul numero dei contatti presenti in rubrica */
int chiave = *num_contatti;

/* se Alloca_Memoria restituisce 1 */
if( Alloca_Memoria( Rubrica, chiave + 1 ) )
{
/* inserisci Contatto */
Menu_Aggiungi_Contatto();
/* assegnazione ID */
Rubrica[chiave]->ID = chiave;

SVUOTA_STDIN;
printf( "Inserisci il nome: " );
Inserisci_Stringa( Rubrica[chiave]->Nome );
printf( "Inserisci il cognome: " );
Inserisci_Stringa( Rubrica[chiave]->Cognome );

chiave++;
*num_contatti = chiave;
Pausa();
}
else
{
printf("Impossibile aggiungere il contatto! Memoria non disponibile.\n");
Pausa();
}

}La prima volta, quando (chiave == 0), la procedura funziona senza errori, appena si vuole scrivere un secondo contatto (chiave == 1) - sulla riga che ho evidenziato in grassetto, il programma va in Seg.Fault!

La cosa... (Gravissima) è che non riesco a capire il perchè! :(

andbin
03-11-2006, 09:57
Rubrica[chiave]->ID = chiave;
(*Rubrica)[chiave].ID = chiave;

Starise
03-11-2006, 10:29
(*Rubrica)[chiave].ID = chiave;Grande! Funziona... il problema è che non capisco perchè usando la freccetta (->) non va!

andbin
03-11-2006, 10:48
Grande! Funziona... il problema è che non capisco perchè usando la freccetta (->) non va!Il problema non è tanto nella freccetta. Te lo spiego meglio:

Supponiamo che tu con malloc/realloc, allochi un certo numero di CONTATTI.
+---------+
| | 1000
+---------+
| | 1010
+---------+
| | 1020
+---------+
....
Non so quanto è grande CONTATTI, supponiamo 10. Nel mio esempio i contatti partono dall'indirizzo 1000.

Poi hai una variabile che tiene il puntatore a questi contatti, per esempio:
+---------+
| 1000 | 2000
+---------+
Tu alla funzione Aggiungi_Contatto passi 2000, cioè l'indirizzo della variabile che tiene il puntatore ai contatti.
Quindi devi "indicizzare" il puntatore ai contatti che è (*Rubrica)[i] e non Rubrica[i]

Facendo ad esempio Rubrica[1], tu prenderesti il contenuto della cella all'indirizzo 2004. Cosa sbagliata, ovviamente.


EDIT Aggiungo questo: se ti chiedi perchè tu hai usato '->' mentre io il punto '.' è semplice. Rubrica[i] è un puntatore (hai dereferenziato solo 1 volta Rubrica) mentre (*Rubrica)[i] è già la struttura CONTATTI (ho dereferenziato 2 volte Rubrica) e quindi ci vuole il punto.

Starise
03-11-2006, 16:48
Grazie per le risposta, sei stato chiarissimo!