Problem mit dynamischen Structuren



  • Hallo zusammen,

    ich bastel derzeit an meinem größten Programm und habe jetzt
    bedingt dadurch dass ich zum erstenmal mit dynamischen Speicher
    arbeite ein ziemlich fieses Problem.

    Alles sollte richtig NULL-Terminiert, allociert und inizialisiert sein.
    Aber dennoch habe ich das Problem, dass ich die Structur "struc_b" nicht
    richtig mit Werten aus "struc_a" gefüllt bekomme.

    Grober Ablauf des Programms (wenn nötig):
    Der User gibt alle möglichen Dateien ein.
    Es wird erstmal ein alement von struc_tab mit pointern auf struc_a und struc_b allociert.
    Danach wird für jede Datei je ein Element von struc_a und struc_b allociert.
    Wenn das alles geklappt hat, und das hat es, dann wird erst struc_a mit den allgemeinen Datei-Infos gefüllt (Name, Typ, größe etc.), aus den Daten von struc_a wird ein Dateiheader für das Archiv (wie ein WinZip-Archiv) generiert und zum Schluss die jeweiligen Header für die Dateien (struc_b) teils aus struc_a (Name und Größe) generiert.

    Das Problem ist nun die generierung von struc_b aus struc_a.:
    Gebe ich beispielsweise 3 Dateien ein wir später nur das erste Element von
    struc_b gefüllt, alle weiteren jedoch nicht.
    Merkwürdig ist, das vor dem späteren Speichern von struc_b die Daten von der
    letzten Datei statt der ersten drinne steht (obowhl ich das 0te hole).
    Aber, und jetzt kommst: er schreibt datsächlich das erste Element von struc_b in die Datei (ist richtig) aber diese Structur wird in der Datei falsch dargestellt (Zahlen kann ich natürlich nicht lesen, aber die Char-Arrays sind normalerweise lesbar und die sind total falsch).

    So, nun zu den Code-Schnippseln. Die sind natürlich nicht vollständig, da
    das ganze sonst zu unübersichtlich wäre:

    /* Funktion: eingabe.c */
    ...
    inizialisierung
    eingabe der dateien
    blabla
    ...
    
    	p_sp		= (XSP*)0;					/* struc_tab */
    	p_sp		= calloc( 1, sizeof( XSP ) );
    
    	if( !komprimieren )
    	{
    		p_sp->p_fz	= calloc( (anz + 1),  sizeof( ZFILE ) ); /* struc_a */
    		p_sp->x_arc	= calloc( (anz + 1),  sizeof( FARC ) );  /* struc_b */
    
    		x_com_dec = 0;
    		x_anz = anz;
    
    		...
    		ein bissel blabla
    		...
    
    	}
    	else
    	{
    		x_com_dec = 1;
    	};
    
    	p_sp->p_fzip = calloc( 1, sizeof( FZIP ) );
    
    	if( p_sp->p_fzip == NULL )
    	{
    		fprintf( stderr, "---> Kein Speicher verfügbar!\n" );
    		return NULL;
    	};
    
    	if( x_dat != NULL ) { fclose( x_dat ); };
    	return p_sp;
    
    ...
    zurück in die Main-Funktion
    Weiter in einer weiteren Funktion
    wo dann wiederum eine andere Funktion aufgerufen wird:
    gen_dinfo: alle Elemente von struc_a werden gefüllt
    Nun gen_archive:
    
    EXPORT XSP* gen_archiv( p_sp )
    
    	XSP*	p_sp;
    {
    	ZFILE*	p_dat	= (ZFILE*)0;
    	FARC*	p_arc	= (FARC*)0;
    	int	ii	= 0;
    
    	fprintf( stderr, "---> Schreibe Archiv-Daten                        " );
    
    	for( ii = 0; ii < x_anz; ii++ )
    	{
    		p_dat = &p_sp->p_fz[ii];
    		p_arc = &p_sp->x_arc[ii];
    
    		strncpy( faname, fname, Lfname );
    		fagroesse	= flaenge;
    		facrypt		= 0;
    		facom		= x_com_dec;
    		strncpy( fanichts, NICHTS, 10 );
    
    		p_dat = (ZFILE*)0;
    		p_arc = (FARC*)0;
    
    	};
    
    	fprintf( stderr, "Done!\n" );
    	return p_sp;
    };
    
    Jetzt wird noch der Header für die Output-Datei generiert und in die output-Datei geschrieben (als Struct).
    So gehts nun weiter:
    
    inizialisierung blabla...
    gen_dtinfo etc. wird aufgerufen...
    
    	for( ii = 0; ii < x_anz; ii++ )
    	{
    		p_dat = &p_sp->p_fz[ii];
    		p_arc = &p_sp->x_arc[ii];
    		x_dat = fopen( feingabe, "rb" );
    		fwrite( p_arc, sizeof(FARC), 1, x_tmp );
    
    		fprintf( stderr, "-> Komprimierung von Datei '%s'", fname );
    
    		/* ---------------------------------------------------- *
    		 * 64KB holen und komprimieren:
    		 * ---------------------------------------------------- */
    		if( flaenge < 65536 )
    		{
    			bloecke		= 1;
    			speicherlaenge	= flaenge;
    		}
    		else
    		{
    			bloecke		= ( flaenge / 65536 ) + 1;
    			speicherlaenge	= 65536;
    		};
    
    		for( jj = 0; jj < bloecke; jj++ )
    		{
    			fread( x_buf1, sizeof(char), speicherlaenge, x_dat );
    
    			/* algos */
    
    			fwrite( x_buf1, sizeof(char), speicherlaenge, x_tmp );
    
    			if( (jj+2) == bloecke )
    			{
    				speicherlaenge = (flaenge - ( (bloecke-1) * speicherlaenge ));
    			};
    		};
    
    		fclose( x_dat );
    		fprintf( stderr, " Fertig!\n" );
    	};
    
    ende....
    

    Wundert euch nicht über die Variablen. Ein Beispiel wie es in der Header.h aussieht:

    struct	x_sp  /* die oben erwähnte struc_tab */
    {
    	int		anz;
    
    	short		f_com_dec;
    	short		f_options	[Lfoptions+1];
    	char		f_pfad_neu	[Lfpfad+1];
    
    	char		f_tname		[Lfname+1];
    
    	char		buffer1[65536 + 1];
    	char		buffer2[65536 + 1];
    
    	ZFILE*		p_fz;      /* struc_a */
    	FARC*		x_arc;     /* struc_b */
    	FZIP*		p_fzip;
    };
    
    typedef struct x_sp		XSP;
    
    #define	x_anz			p_sp->anz
    #define	x_tname			p_sp->f_tname
    #define	x_pfadn			p_sp->f_pfad_neu
    #define	x_com_dec		p_sp->f_com_dec
    #define x_options		p_sp->f_options
    #define	x_buf1			p_sp->buffer1
    #define	x_buf2			p_sp->buffer2
    

    Kann mir einer von euch sagen, wieso struc_b trotz vorhandener Daten bei struc_a nicht gefüllt wird?
    Wo mache ich da etwas falsch?

    Gruß,
    Hagge
    PS: Entschuldigt die wenigen Kommentare, bin noch am ausprobieren.
    Wenn das Problem gelöst ist, würde ich alles noch mal überarbeiten und
    mich dann an's wesendliche machen.



  • Hallo,

    ich habe mir jetzt deinen Code angesehen. Meinst du wirklich, dass
    dir mit den Informationen, die du uns gibst, geholfen werden kann.

    Z.B. den folgenden Ausschnitt:

    for( ii = 0; ii < x_anz; ii++ ) 
         { 
             p_dat = &p_sp->p_fz[ii]; 
             p_arc = &p_sp->x_arc[ii]; 
    
             strncpy( faname, fname, Lfname ); 
             fagroesse    = flaenge; 
             facrypt        = 0; 
             facom        = x_com_dec; 
             strncpy( fanichts, NICHTS, 10 ); 
    
             p_dat = (ZFILE*)0; 
             p_arc = (FARC*)0; 
    
         };
    

    Was sind fagroesse, facrypt, ...?

    Sind denn die Daten in p_sp richtig gespeichert?
    Kannst dir ja mal print Funktionen schreiben, die deine Daten auf
    den Bildschirm ausgeben.

    Wenn deine Daten alle korrekt in p_sp vorliegen, kannst du dann ja mit
    printf-Anweisungen mal ausgeben, welche Daten wann in die Datei geschrieben
    werden.

    Ansonsten kann ich dir so nicht wirklich weiterhelfen, da dein geposteter
    Code zu viele Lücken hat.

    Gruß mcr



  • Wie heißt es so schön: Poste einen kompilierbaren minimalen Code, der dein Problem illustriert. Die wenigsten Leute werden sicher Lust haben über hundert Zeilen Code-Fitzel durchzulesen um dein Problem zu suchen.



  • Moin,

    erstmal vielen Dank für die Kritik 😃

    mcr schrieb:

    Hallo,
    Was sind fagroesse, facrypt, ...?
    Gruß mcr

    Kleiner ausschnit aus dem Header:

    struct	x_archiv
    {
    	char		xa_name		[Lfname + 1];
    	unsigned long	xa_groesse;
    	short		xa_crypt;
    	short		xa_com;
    	char		xa_nichts	[10 + 1];
    };
    
    typedef	struct x_archiv	FARC;
    
    #define	faname		p_arc->xa_name
    #define	fagroesse	p_arc->xa_groesse
    #define	facrypt		p_arc->xa_crypt
    #define	facom		p_arc->xa_com
    #define	fanichts	p_arc->xa_nichts
    

    Habe den Fehler nun gefunden - es lag an den obigen Defines
    die z.B. so aussahen:
    #define faname p_sp->x_arc->xa_name

    Wodurch immer auf das erste Element verwiesen wurde...
    Das konnte ja nun nicht funktionieren 🕶

    Nun ja, man lernt nie aus: das nächste mal achte ich mehr auf meine Defines 😛

    Gruß und vielen Dank,
    Hagge die Bagge


Anmelden zum Antworten