Προς το περιεχόμενο

κάπως περίεργο fscanf


jimbakl

Προτεινόμενες αναρτήσεις

Δημοσ.

η εκφώνηση δεν λέει κάτι, την έχω κάνει την άσκηση, είναι ένα πρόβλημα δρομολόγησης, απλά πρέπει να την κάνω τώρα να διαβάζει τα δεδομένα από ένα txt αρχείο και όχι να τα δηλώνω εγώ στην αρχή..

 

να υπενθυμίσω.. στο τχτ που παραθέτω τα δεδομένα παραπάνω, το πρώτο νούμερο στην περίπτωσή μου το 6 είναι ο αριθμός των πελατών.. η 1η επόμενη σειρά θα είναι ο πίνακας profit[6] και απο την αποκάτω σειρά μέχρι το τέλος θα ειναι ο πίνακας των αποστάσεων dis[6][6]..

εγώ θέλω να τα διαβάσω..

 

αυτα τα πράγματα είναι τα float **myarray; και όπου έχει * ή ** από ότι έχω βρεί είναι τα structs ???.. το θέμα είναι πως δεν μπορώ κάπου να διαβάσω για να καταλάβω τί παίζει με αυτά.. αυτό που έχω κάνει εγώ είναι το παρακάτω

 

 

 

>#include<stdio.h>
#include<stdlib.h>

main()
{
   int i,N,j,length;
   float data[400]; // pinakas poy bazo ta dedomena
float profit[N];
float dis[N][N];
FILE*infile;
infile=fopen("dataRouting.txt","r");
if(infile==NULL)
{
printf("Cannot open the file\n");
exit(1);
}
printf("data:\n");
i=0;
while(fscanf(infile,"%f",&data[i])!=EOF)
{
	printf("%.2f\t",data[i]);
       i++;	
   }
   length=i;
  	fclose(infile);
   	
  	// MORFOPOIISI TOY data[] kai DIMIOURGIA TWN PRAGMATIKWN PINAKWN dis, profit
   
   N=data[0]; // N einai o # twn pelatwn 
   printf("\n\nN=%.1d\n",N);	
   
   // dimiourgia pinaka profit[]
   printf("\n\nprofit=\t");                                                                                                                                                          
  	for(i=1;i<N+1;i++)                                                                                                                                                                  
  	{
   profit[i-1]=data[i];        //synexizw apo to data[1] mexri  to data[N] kai                                                                                                                                                           
   printf("%.1f\t",profit[i-1]);// bazo times ston pinaka profit arxizontas apo 
   }                            // to profit[0]
    printf("\n\n");
   // dimiourgia pinaka dis[][]
   for(i=N+1;i<length;i++)
   {
   printf("%.1f\t",data[i]);
   }
   printf("\n");

   for(i=N+1;i<length+1;i+=N)
   {
        for(j=N+1;j<length;j++)
        {
        dis[i][j]=data[i][j];
        printf("%.1f",dis[i][j]);
        }     
        printf("\n");
   }
   printf("\n");
  
system("pause");
}


και βγάζει αυτά τα λάθη
[code]29 [Warning] converting to `int' from `float' 
51  invalid types `float[int]' for array subscript 

 

Το warning μπορείς να το φτιάξεις βάζοντας: N=(int)data[0];

Τώρα το άλλο:

>
float profit[N];
float dis[N][N];

Δεν μπορεί να γίνει κάτι τέτοιο, ή πρέπει να ξέρεις από την αρχή το μέγεθος του πίνακα ή μετά με malloc (αν είναι μονοδιάστατος) ή με calloc (αν είναι δισδιάστατος) να τους δώσεις ένα μέγεθος. Επίσης, έχεις:

>
dis[i][j]=data[i][j];

Αφού ο ένας είναι μονοδιάστατος και ο άλλος δισδιάστατος, πώς θα γίνει κάτι τέτοιο;

  • Απαντ. 32
  • Δημ.
  • Τελ. απάντηση
Δημοσ.

@migf1

Ο κώδικας που παρέθεσα είναι ένα απλό sample που δείχνει πως φτιάχνουμε δυναμικά έναν πίνακα. Νομίζω πως επιπλέον κώδικας (για ελέγχους, κτλ) μπορεί να λείπει από το sample για να είναι πιο κατανοητό σε αυτόν που το διαβάζει.

 

Σίγουρα σε production περιβάλλον η χρήση της free() είναι απαραίτητη, όπως και οι σχετικοί έλεγχοι για τη malloc.

 

@jimbakl

Ο κώδικας που έκανα post γεμίζει δισδιάστατο πίνακα. Διάβασε τον λίγο και θα μπορέσεις να γράψεις και το κομμάτι κώδικα που θα γεμίζει το μονοδιάστατο πίνακα. Μία μεταβλητή τύπου float * είναι ένας δείκτης (pointer κοινώς) σε μία μεταβλητή τύπου float. Μία μεταβλητή τύπου float ** είναι ένας διπλός δείκτης. Δεν είναι structs, μπορείς όμως να φτιάξεις και pointers που δείχνουν σε structs.

 

Αν δεν γνωρίζεις περί pointers καλό είναι να διαβάσεις λίγο πρώτα, ίσως το παράδειγμα με τον διπλό δείκτη να είναι βαρύ για πρώτη επαφή.

Δημοσ.

...

Τώρα το άλλο:

>
float profit[N];
float dis[N][N];

Δεν μπορεί να γίνει κάτι τέτοιο, ή πρέπει να ξέρεις από την αρχή το μέγεθος του πίνακα ή μετά με malloc (αν είναι μονοδιάστατος) ή με calloc (αν είναι δισδιάστατος) να τους δώσεις ένα μέγεθος.

...

Από το C99 στάνταρ και μετά υποστηρίζονται variable-length arrays, οπότε μπορεί να αποφευχθεί η χρήση των calloc()/malloc()/realloc() και free().

 

ΥΓ. Θα δω τον κώδικα σε καμιά ωρίτσα, ίσως λίγο νωρίτερα.

Δημοσ.

σας ευχαριστώ πολύ..έχω το βιβλίο του kernighan και ritchie Και το διαβαζω τώρα μπας και καταλάβω τίποτα.. το θέμα είναι πως στην σχολή δεν είχαμε ασχοληθεί καθόλου με pointers και τπτ πιο δύσκολο στον προγραμματισμό, και τώρα για την πτυχιακή μου θέλει δουλειά.. χαζομάρα μου που δεν το έψαξα στην ώρα του λίγο παραπάνω...

Δημοσ.

Από το C99 στάνταρ και μετά υποστηρίζονται variable-length arrays, οπότε μπορεί να αποφευχθεί η χρήση των calloc()/malloc()/realloc() και free().

Ναι, όντως, τώρα το πρόσεξα κι εγώ. Πάντως τα υπόλοιπα που είπα ελπίζω να ισχύουν...
Δημοσ.

 

 

OFFTOPIC

Ρε συ mig, εσύ που θυμάσαι τα πρότυπα κτλ... με τα incomplete structs τι παίζει; Υποστηριζόντουσαν "από πάντα" (δύσκολο) ; Εάν όχι, θυμάσαι πότε μπήκαν;

 

Βασικά πες μου ότι θυμάσαι - ξέρεις το πότε... για να μην ψάχνω :P

 

Thnx in advance!

 

 

 

Δημοσ.

 

 

OFFTOPIC

Ρε συ mig, εσύ που θυμάσαι τα πρότυπα κτλ... με τα incomplete structs τι παίζει; Υποστηριζόντουσαν "από πάντα" (δύσκολο) ; Εάν όχι, θυμάσαι πότε μπήκαν;

 

Βασικά πες μου ότι θυμάσαι - ξέρεις το πότε... για να μην ψάχνω :P

 

Thnx in advance!

 

 

 

 

 

Νομίζω από πάντα. Αν όχι από πάντα, τότε από το C89 (ANSI) αλλά νομίζω από πάντα!

 

Κυρίως χρησιμοποιούνται για Data Encapsulation και μπορείς να τα διαχειριστείς μονάχα με δείκτες. Παραθέτω 2 σχετικά αρθράκια:

http://www.ibm.com/d...ary/pa-ctypes1/ (κύλα μεχρι να βρεις: Incomplete Types)

http://tinobox.com/w...-c-programming/

 

 

Δημοσ.

σας ευχαριστώ πολύ..έχω το βιβλίο του kernighan και ritchie Και το διαβαζω τώρα μπας και καταλάβω τίποτα.. το θέμα είναι πως στην σχολή δεν είχαμε ασχοληθεί καθόλου με pointers και τπτ πιο δύσκολο στον προγραμματισμό, και τώρα για την πτυχιακή μου θέλει δουλειά.. χαζομάρα μου που δεν το έψαξα στην ώρα του λίγο παραπάνω...

Σορρυ για την καθυστέρηση, τώρα όμως "άδειασα".

 

Λοιπόν ως γενική αρχή εγώ αποφεύγω δια ροπάλου τη χρήση των συναρτήσεων scanf() και fscanf() κι αντί αυτών προτιμώ να διαβάζω το input ανά γραμμή, ως string, με την fgets() από τις έτοιμες συναρτήσεις (ή κάποιες αντίστοιχες custom που έχω φτιάξει).

 

Στην προκειμένη περίπτωση για παράδειγμα, δεν είμαι καθόλου σίγουρος πως το...

>
for(j=0;j<n;j++){
   fscanf(infile,"%f",&profit[j]);}
}

λειτουργεί όπως επιθυμείς με τη συγκεκριμένη δομή του αρχείου σου (και δεν θέλω να μάθω κιόλας, για μένα οι scanf() και fscanf() είναι σαν να μην υπάρχουν καθόλου στη γλώσσα).

 

Οπότε σου έγραψα κώδικα, ο οποίος διαβάζει την κάθε γραμμή του αρχείου σε ένα string: line, με χρήση της fgets(). Το string αυτό είτε απλά το μετατρέπει σε int αν πρόκειται για την 1η γραμμή του αρχείου, είτε το σπάει σε κομμάτια (πλήθους όσους λέει η 1η γραμμή), τα οποία κομμάτια μετατρέπει σε τιμές που αποθηκεύει στους πίνακες: prof[ ] και dis[ ][ ].

 

>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAXLINELEN	255+1

// -------------------------------------------------------------------------------------
int s_tokenscount(char *s, char *tokens[], const char *delimiters)
{
if ( !s || !tokens || !delimiters )
	return 0;

register int i=0;

tokens[0] = strtok(s, delimiters);
if (tokens[0] == NULL)
	return 0;
for (i=1; (tokens[i]=strtok(NULL, delimiters)) != NULL; i++)
	; 

return i;
}
// -------------------------------------------------------------------------------------
int s_tokenize(char *s, char *tokens[], const int maxtokens, const char *delimiters)
{
if ( !s || !tokens || !delimiters )
	return 0;

register int i=0;

tokens[0] = strtok(s, delimiters);
if (tokens[0] == NULL)
	return 0;
for (i=1; i < maxtokens && (tokens[i]=strtok(NULL, delimiters)) != NULL; i++)
	; 

return i;
}
// -------------------------------------------------------------------------------------
void print_profits( const int ncustomers, const float prof[] )
{
register int i = 0;

for (i=0; i < ncustomers; i++)
		printf("%.2f ", prof[i] );
putchar('\n');

return;
}// -------------------------------------------------------------------------------------
void print_distances( const int ncustomers, float dis[][ncustomers] )
{
register int i = 0, j = 0;

for (i=0; i < ncustomers; i++)
{
	for (j=0; j < ncustomers; j++)
		printf("%.2f ", dis[i][j] );
	putchar('\n');
}

return;
}
// -------------------------------------------------------------------------------------
int main( void )
{
int ncustomers = 0;			// πλήθος πελατών (1η γραμμή στο αρχείο)
char line[ MAXLINELEN ] = {'\0'};	// για διάβασμα μιας γραμμής από αρχείο

// άνοιγμα αρχείου για διάβασμα

FILE *infile = fopen("dataRouting.txt", "r");
if ( !infile )
{
	puts("*** file read error: aborting program...");
	exit( EXIT_FAILURE );
}

// διάβασμα 1ης γραμμής & ανάθεση τιμής στο: ncustomers

if ( !fgets(line, MAXLINELEN, infile ) )
{
	puts("*** file read error: (line #1), aborting program...");
	fclose( infile );
	exit( EXIT_FAILURE );
}
ncustomers = atoi( line );

char *linetokens[ ncustomers ];		// πίνακας από strings (tokens γραμμής)
float prof[ ncustomers ];		// πίνακας κερδών (2η γραμμή στο αρχείο)
float dis[ ncustomers ][ ncustomers ];	// αποστάσεις (υπόλοιπες γραμμές αρχείου)
register int i=0, j=0;			// απλοί μετρητές

// διάβασμα αρχείου από την αρχή ανά γραμμή & ανάθεση τιμών στους prof & dis

rewind( infile );			// τοποθέτηση στην αρχή του αρχείου
for (i=0; fgets(line, MAXLINELEN, infile);  i++ )
{
	// αγνόηση 1ης γραμμής
	if ( i == 0 )
		continue;

	// σπάσιμο γραμμής σε tokens
	s_tokenize(line, linetokens, ncustomers, " \n" );

	// η 2η γραμμή περιέχει τις τιμές για τον πίνακα prof[]
	if ( i == 1 )
		for (j=0; j < ncustomers; j++)
			prof[j] = atof( linetokens[j] );

	// οι υπόλοιπες γραμμές περιέχουν τιμές για τον πίνακα dis[][]
	else
		for (j=0; j < ncustomers; j++)
			dis[i-2][j] = atof( linetokens[j] );
}

fclose( infile );			// κλείσιμο του αρχείου

printf("ncustomers = %d\n", ncustomers );
print_profits( ncustomers, prof );
print_distances( ncustomers, dis );

system("pause");

exit( EXIT_SUCCESS );
}

 

Ο κώδικας είναι strictly C99 standard, οπότε γίνεται compile μόνο σε compilers που το υποστηρίζουν. Αν θες να είναι ANSI compliant (C89) τότε θα πρέπει να χρησιμοποιήσεις δυναμική διαχείριση μνήμης για τους πίνακες, με δείκτες, όπως σου έδειξε ο φίλος tasos.

 

Επίσης, στον κώδικα υποθέτω πως το αρχείο είναι ΣΩΣΤΑ δομημένο, οπότε δεν κάνω ελέγχους για αρχεία με "ασυνεπή" περιεχόμενο. Σου έχω βαλει όμως μια συνάρτηση: s_tokenscount() την οποία μπορείς να χρησιμοποιήσεις για να ελέγχεις αν τα tokens της κάθε γραμμής που διαβάζεις από το αρχείο συνάδουν με το πλήθος των μεταβλητών που περιμένεις να έχει η γραμμή αυτή (να "πιάνεις" δηλαδή potential errors πριν συμβούν).

 

Εγώ αντί αυτής της συνάρτησης χρησιμοποιώ την s_tokenize() (στην έχω βάλει κι αυτή) η οποία σπάει τη γραμμή σε όσα tokens της πεις, χωρίς όμως να διενεργεί άλλους ελέγχους.

Δημοσ.

...

Ο κώδικας είναι strictly C99 standard, οπότε γίνεται compile μόνο σε compilers που το υποστηρίζουν. Αν θες να είναι ANSI compliant (C89) τότε θα πρέπει να χρησιμοποιήσεις δυναμική διαχείριση μνήμης για τους πίνακες, με δείκτες, όπως σου έδειξε ο φίλος tasos.

...

Στον έγραψα και σε ANSI standard, για να έχεις ένα μέτρο σύγκρισης. Όπως θα διαπιστώσεις, σε ANSI θέλει αρκετή παραπάνω δουλίτσα, την οποία την έχω διασπάσει σε συναρτήσεις ;)

 

>
#include <stdio.h>
#include <stdlib.h>			/* για calloc(), free(), atoi(), atof(), exit() */
#include <string.h>			/* για strtok() ...             				*/

#define MAXLEN_LINE		255+1
#define MAXLEN_LINETOKEN	10+1

typedef enum Bool {FALSE=0, TRUE} Bool;

/* ------------------------------------------------------------------------------------- */
int s_tokenscount(char *s, char *tokens[], const char *delimiters)
{
register int i=0;

if ( !s || !tokens || !delimiters )
	return 0;

tokens[0] = strtok(s, delimiters);
if (tokens[0] == NULL)
	return 0;
for (i=1; (tokens[i]=strtok(NULL, delimiters)) != NULL; i++)
	; 

return i;
}
/* ------------------------------------------------------------------------------------- */
int s_tokenize(char *s, char *tokens[], const int maxtokens, const char *delimiters)
{
register int i=0;

if ( !s || !tokens || !delimiters )
	return 0;

tokens[0] = strtok(s, delimiters);
if (tokens[0] == NULL)
	return 0;
for (i=1; i < maxtokens && (tokens[i]=strtok(NULL, delimiters)) != NULL; i++)
	; 

return i;
}
/* ------------------------------------------------------------------------------------- */
float **dis_create( const int ncustomers )
{
float **dis = NULL;
register int i=0, j=0;

dis = (float **) calloc(ncustomers, sizeof(float *) );
if ( !dis )
	return NULL;

for (i=0; i < ncustomers; i++)
{
	dis[i] = (float *) calloc(ncustomers, sizeof(float) );
	if ( !dis[i] )
	{
		for (j=i-1; j > -1; j--) {
			free( dis[j] );
			dis[j] = NULL;
		}
		free( dis );
		return NULL;
	}
}

return dis;
}
/* ------------------------------------------------------------------------------------- */
void dis_free( float **dis, const int ncustomers )
{
register int i = 0;

if ( !dis )
	return;

for (i=0; i < ncustomers; i++)
{
	if ( dis[i] ) {
		free( dis[i] );
		dis[i] = NULL;
	}
}

if ( dis )
	free( dis );
dis = NULL;

return;
}
/* ------------------------------------------------------------------------------------- */
char **linetokens_create( const int ncustomers, const int maxtokenlen )
{
char **linetokens = NULL;
register int i=0, j=0;

linetokens = (char **) calloc( ncustomers, sizeof(char *) );
if ( !linetokens )
	return NULL;

for (i=0; i < ncustomers; i++)
{
	linetokens[i] = (char *) calloc(maxtokenlen, sizeof(char) );
	if ( !linetokens[i] )
	{
		for (j=i-1; j > -1; j--) {
			free( linetokens[j] );
			linetokens[j] = NULL;
		}
		free( linetokens );
		return NULL;
	}
}

return linetokens;
}
/* ------------------------------------------------------------------------------------- */
void linetokens_free( char **linetokens, const int ncustomers )
{
register int i = 0;

if ( !linetokens )
	return;

for (i=0; i < ncustomers; i++)
{
	if ( linetokens[i] ) {
		free( linetokens[i] );
		linetokens[i] = NULL;
	}
}

if ( linetokens )
	free( linetokens );
linetokens = NULL;

return;
}
/* ------------------------------------------------------------------------------------- */
Bool memory_reserve( 
float **prof, float ***dis, char ***linetokens,
const int ncustomers, const int maxtokenlen
)
{
*prof = calloc(ncustomers, sizeof(float) );
if ( !*prof )
	return FALSE;

*dis = dis_create( ncustomers );
if ( !*dis )
{
	free( *prof );
	*prof = NULL;

	return FALSE;
}

*linetokens = linetokens_create( ncustomers, maxtokenlen );
if ( !*linetokens )
{
	free( *prof );
	*prof = NULL;

		dis_free( *dis, ncustomers );

	return FALSE;
}

return TRUE;
}
/* ------------------------------------------------------------------------------------- */
void memory_cleanup( float *prof, float **dis, char **linetokens, const int ncustomers )
{
if ( prof )
	free( prof );
prof = NULL;

dis_free( dis, ncustomers );
linetokens_free( linetokens, ncustomers );

return;
}
/* ------------------------------------------------------------------------------------- */
void print_profits( const int ncustomers, const float *prof )
{
register int i = 0;

if ( !prof )
	return;

for (i=0; i < ncustomers; i++)
		printf("%.2f ", prof[i] );
putchar('\n');

return;
}
/* ------------------------------------------------------------------------------------- */
void print_distances( const int ncustomers, float **dis )
{
register int i = 0, j = 0;

if ( !dis || !*dis )
	return;

for (i=0; i < ncustomers; i++)
{
	for (j=0; j < ncustomers; j++)
		printf("%.2f ", dis[i][j] );
	putchar('\n');
}

return;
}
/* ------------------------------------------------------------------------------------- */
int main( void )
{
int ncustomers = 0;			/* πλήθος πελατών (1η γραμμή στο αρχείο) */
char line[ MAXLEN_LINE ] = {'\0'};	/* για διάβασμα μιας γραμμής από αρχείο  */
float *prof = NULL;			/* πίνακας κερδών (2η γραμμή στο αρχείο) */
float **dis = NULL;			/* αποστάσεις (υπόλοιπες γραμμές αρχείου)*/
char **linetokens = NULL;		/* πίνακας από strings (tokens γραμμής)  */
register int i=0, j=0;			/* απλοί μετρητές                    	*/

/* άνοιγμα αρχείου για διάβασμα */
FILE *infile = fopen("dataRouting.txt", "r");
if ( !infile )
{
	puts("*** file read error: aborting program...");
	exit( EXIT_FAILURE );
}

/* διάβασμα 1ης γραμμής & ανάθεση τιμής στο: ncustomers */
if ( !fgets(line, MAXLEN_LINE, infile ) )
{
	puts("*** file read error: (line #1), aborting program...");
	fclose( infile );
	exit( EXIT_FAILURE );
}
ncustomers = atoi( line );

/* δέσμευση δυναμικής μνήμης για τους πίνακές μας */
if ( !memory_reserve( &prof, &dis, &linetokens, ncustomers, MAXLEN_LINETOKEN ) )
{
	puts("*** out of memory: aborting program...");
	fclose( infile );
	exit( EXIT_FAILURE );
}

/* διάβασμα αρχείου από την αρχή ανά γραμμή & ανάθεση τιμών στους prof & dis */

rewind( infile );			/* τοποθέτηση στην αρχή του αρχείου 	*/
for (i=0; fgets(line, MAXLEN_LINE, infile);  i++ )
{
	/* αγνόηση 1ης γραμμής */
	if ( i == 0 )
		continue;

	/* σπάσιμο γραμμής σε tokens */
	s_tokenize(line, linetokens, ncustomers, " \n" );

	/* η 2η γραμμή περιέχει τις τιμές για τον πίνακα prof[] */
	if ( i == 1 )
		for (j=0; j < ncustomers; j++)
			prof[j] = atof( linetokens[j] );

	/* οι υπόλοιπες γραμμές περιέχουν τιμές για τον πίνακα dis[][] */
	else
		for (j=0; j < ncustomers; j++)
			dis[i-2][j] = atof( linetokens[j] );
}

fclose( infile );			/* κλείσιμο του αρχείου 				*/

printf("ncustomers = %d\n", ncustomers );
print_profits( ncustomers, prof );
print_distances( ncustomers, dis );

/* απελευθέρωση της δυναμικά δεσμευμένης μνήμης */
memory_cleanup( prof, dis, linetokens, ncustomers );

system("pause");

exit( EXIT_SUCCESS );
}

Δημοσ.

Σε ευχαριστώ πάρα πολύ.. Άρχισα να το μελετάω τώρα μπάς και καταλάβω τι γίνεται, είναι λίγο μπέρδεμα αλλά μακάρι να το καταλάβω,

Δημοσ.

 

 

Νομίζω από πάντα. Αν όχι από πάντα, τότε από το C89 (ANSI) αλλά νομίζω από πάντα!

 

Κυρίως χρησιμοποιούνται για Data Encapsulation και μπορείς να τα διαχειριστείς μονάχα με δείκτες. Παραθέτω 2 σχετικά αρθράκια:

http://www.ibm.com/d...ary/pa-ctypes1/ (κύλα μεχρι να βρεις: Incomplete Types)

http://tinobox.com/w...-c-programming/

 

 

 

 

 

Δεν διάβασα τα links... γνωστά τα όσα λες :P

 

Και μην ξεχνάμε τα bit arrays σε C!!! :P :P

 

 

Δημοσ.

 

 

Δεν διάβασα τα links... γνωστά τα όσα λες :P

 

Και μην ξεχνάμε τα bit arrays σε C!!! :P :P

 

 

 

 

 

Οπότε μάλλον δεν κατάλαβα την αρχική ερώτηση. Τι εννοούσες;

 

ΥΓ. Για τα bit-arrays, ο μόνος τρόπος που γνωρίζω είναι με χρήση arrays of unsigned chars ή ints και κατόπιν με bitwise operations πάνω τους: http://c-faq.com/misc/bitsets.html (μπορούν να υλοποιηθούν και με incomplete types; )

 

 

Δημοσ.

Σε ευχαριστώ πάρα πολύ.. Άρχισα να το μελετάω τώρα μπάς και καταλάβω τι γίνεται, είναι λίγο μπέρδεμα αλλά μακάρι να το καταλάβω,

Τίποτα! Βασικά υπάρχει ένα πρόβλημα στην linktokens_free() όπου χτυπάει ένα free() και δεν καταλαβαίνω και γιατί :( ...

 

>
/* ------------------------------------------------------------------------------------- */
void linetokens_free( char **linetokens, const int ncustomers )
{
register int i = 0;

if ( !linetokens )
	return;

for (i=0; i < ncustomers; i++)
{
	if ( linetokens[i] ) {
/*** ΓΙΑΤΙ ΧΤΥΠΑΕΙ AYTO TO free() ;;;;;;;;;;;
		free( linetokens[i] );
***/
		linetokens[i] = NULL;
	}
}

if ( linetokens )
	free( linetokens );
linetokens = NULL;

return;
}

Δημοσ.

Τίποτα! Βασικά υπάρχει ένα πρόβλημα στην linktokens_free() όπου χτυπάει ένα free() και δεν καταλαβαίνω και γιατί :( ...

 

>
/* ------------------------------------------------------------------------------------- */
void linetokens_free( char **linetokens, const int ncustomers )
{
register int i = 0;

if ( !linetokens )
	return;

for (i=0; i < ncustomers; i++)
{
	if ( linetokens[i] ) {
/*** ΓΙΑΤΙ ΧΤΥΠΑΕΙ AYTO TO free() ;;;;;;;;;;;
		free( linetokens[i] );
***/
		linetokens[i] = NULL;
	}
}

if ( linetokens )
	free( linetokens );
linetokens = NULL;

return;
}

Φαίνεται ότι το πρόβλημα στην linetokens_free είναι αποτέλεσμα εσφαλμένης διαχείρισης μνήμης σε προηγούμενη ρουτίνα. Μέσα από μια γρήγορη διαδικασία debugging με απομονώσεις των functions της main(), θεωρώ ότι πρέπει να ελέγξεις την ρουτίνα s_tokenize καθώς η εκτέλεση της οδηγεί ύστερα σε κατάρρευση το linetokens_free. Υπόψη ότι το strtok είναι καταστροφικό για τα περιεχόμενα πχ. του tokens[0][0] οπότε και για την δεσμευμένη μνήμη (τροποποιεί το address του memory block εκ νέου).

 

Υ.Γ.

Όλα αυτά με κάθε επιφύλαξη καθώς είδα το θέμα στα γρήγορα.

 

Καλή συνέχεια!

Δημοσ.

Ναι, αυτή την συνάρτηση ψυλλιάζομαι κι εγώ, αλλά στην linetokens_free() έχω βάλει επί τούτου έλεγχο ώστε να κοιτάει αν το linetokens[ i ] δεν είναι NULL πριν επιχειρήσει να το κάνει free().

Αρχειοθετημένο

Αυτό το θέμα έχει αρχειοθετηθεί και είναι κλειστό για περαιτέρω απαντήσεις.

  • Δημιουργία νέου...