Visualizzazione dei risultati da 1 a 3 su 3
  1. #1

    C Errore stack trace e segm fault

    Salve ragazzi! Sono alle prese con un programmino che mi da difficoltà, leggete il seguito!
    Il programma è cosi strutturato:
    una strut Data con i membri, gg, mm, aa
    Un array dinamico di elementi Data
    4 funzioni:
    -2 funzioni si occupano dell'input:
    -----una si occupa di prendere in input un solo elemento
    -----l'altra chiamando in modo ciclico la precedente memorizza tutti gli elementi fino a che la variab sentinella ctrl vale 1
    -2 funzioni si occupano dell''output
    -----hanno la stessa logica di quelle di input solo che non c'è, ovviamente la sentinella

    Ok ragazzi ecco il codice, spero che ora mi potrete aiutare con piu semplicità :-) vi ringrazio

    codice:
    #include <stdio.h>
    #include <stdlib.h>
    struct Data {
    	int gg;
    	int mm;
    	int aa;
    };typedef struct Data Data;
    
    /* Prototipi */
    Data input_singolo( void );
    void stampa_singolo( Data x );
    int input_tutti( Data* V, int* nE );
    void stampa_tutti( Data* V, int n );
    
    int main(void) {
    
    	Data* Vett = NULL;
    	int numEl = 0;
    	
    	int istr = input_tutti( Vett, &numEl );
    	stampa_tutti( Vett, numEl );
    
    	return 0;
    }
    
    /* Prende in input tutti gli elementi di V.
     * riceve V ed un puntatore alla var numEl.
     * col puntatore salva il numero di elementi dell'array,
     * e ritorna il valore immesso a ctrl */
    int input_tutti( Data* V, int* nE ) {
    	int i = *nE;
    	int ctrl = 0;
    	while( ctrl != 1 ) {
    		V = realloc( V, (i+1)*sizeof(Data) );
    		V[i++] = input_singolo();
    		printf( "Immettere 1 per fermare l'inserimento, immettere 0 per continuare: " );
    		scanf( "%d", &ctrl );
    	}
    	*nE = i;
    	return ctrl;
    }
    
    /* stampa tutti gli elementi di V  */
    void stampa_tutti( Data* V, int n ) {
    	for( int i = 0; i < n; i++ ) {
    		stampa_singolo( V[i] );
    	}
    }
    
    /* prende in input un elemento di tipo Data */
    Data input_singolo( void ) {
    	Data x;
    	printf("Inserire data (g/m/a): ");
    	scanf( "%d/%d/%d", &x.gg, &x.mm, &x.aa );
    	return x;
    }
    
    /* stampa singolo elemento */
    void stampa_singolo( Data x ) {
    	printf("%d/%d/%d\n", x.gg, x.mm, x.aa);
    }
    Errore:
    3@tre ~
    $ gcc -Wall -std=c99 a.c -o a.exe
    a.c: In function ‘main’:
    a.c:20:6: warning: unused variable ‘istr’

    3@tre ~
    $ ./a.exe
    Inserire data (g/m/a): 29/7/1990
    Immettere 1 per fermare l'inserimento, immettere 0 per continuare: 0
    Inserire data (g/m/a): 7/6/1991
    Immettere 1 per fermare l'inserimento, immettere 0 per continuare: 1
    Exception: STATUS_ACCESS_VIOLATION at eip=00401283
    eax=00000000 ebx=00000000 ecx=20000037 edx=00000000 esi=61268A54 edi=6119DD5F
    ebp=0022CC98 esp=0022CC70 program=C:\cygwin\home\3\a.exe, pid 1668, thread main
    cs=001B ds=0023 es=0023 fs=003B gs=0000 ss=0023
    Stack trace:
    Frame Function Args
    0022CC98 00401283 (00000000, 00000002, 0022CCE8, 49435341)
    0022CCC8 004011BA (00000001, 0022CCF0, 20010100, 612671DE)
    0022CD58 61006EE8 (00000000, 0022CDA8, 610064E0, 00000000)
    End of stack trace
    Segmentation fault (core dumped)

    3@tre ~
    $

  2. #2
    Utente bannato
    Registrato dal
    Oct 2010
    Messaggi
    1,219
    Hai fatto bene a postare l' input del terminale, così è chiaro.
    Innanzitutto con la realloc,siccome ritorna un puntatore a void, anche se il tipo Data* è compatibile col tipo void*,è sempre meglio effettuare un cast a Data*.
    Poi tu passi come parametro Vett, che è un puntatore.
    Ma il puntatore originario rimane intatto: infatti se provi a stampare dopo la chiamata a input_tutti il valore di Vett, è sempre NULL.
    La input_tutti, come una qualsiasi altra funzione, fa solo una copia di quel puntatore.
    Per cui alla fine della funzione avrai perso il riferimento a quella memoria.
    Altra cosa: chiami la realloc senza che ci sia stata allocata memoria.Quando i=1 chiama la malloc.
    Inoltre è meglio controllare che la malloc e la realloc non ritornino NULL.
    Puoi usare le asserzioni di assert.h , o exit(int).
    Ecco il codice corretto:
    codice:
    int input_tutti( Data** V, int* nE ) {
    	int i = *nE;
    	int ctrl = 0;
    	while( ctrl != 1 ) {
    	    i++;
    	    if(i>1)
    		    *V = (Data*)realloc( *V, i*sizeof(Data) );
                else
                        *V=(Data*)malloc(sizeof(Data));
                assert(*V!=NULL);  
    	    (*V)[i-1] = input_singolo();
    	    printf( "Immettere 1 per fermare l'inserimento, immettere 0 per continuare: " );
    	    scanf( "%d", &ctrl );
    	    }
    	*nE = i;
    	return ctrl;
    }

  3. #3
    Chiarissimo e gentilissimo, ti ringrazio tanto

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.