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

Stack overflow in your program's main thread


kal03

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

...

θέλω να εισάγω στοιχεια σε μια στοιβα...

και μετα να τα "παω" αυτά σε μια άλλη κενή..(αυτή ειναι η βασική ιδέα)

...

 

Προσάρμοσέ το...

 

Κώδικας

 

 

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

#define pressENTER()								\
	do{									\
		int c;								\
		printf( "press ENTER..." );					\
		while ( '\n' != (c=getchar()) && EOF != c )			\
			;							\
	}while(0)

typedef struct node {
	int val;
	struct node *back;
}Node;

/*********************************************************//**
 *
 ************************************************************/
void stack_push( Node **stack, int val )
{
	if ( !stack ) {
		return;
	}

	Node *node = malloc( sizeof(Node) );
	if ( !node ) {
		fputs( "*** malloc() failed!\n", stderr );
		return;
	}

	node->val = val;
	node->back = *stack;
	*stack = node;
}

/*********************************************************//**
 *
 ************************************************************/
int stack_pop( Node **stack )
{
	if ( !stack || !*stack ) {
		return -1;
	}

	int ret = (*stack)->val;
	Node *back = (*stack)->back;
	free( *stack );
	*stack = back;

	return ret;
}

/*********************************************************//**
 *
 ************************************************************/
void stack_destroy( Node **stack )
{
	if ( !stack || !*stack ) {
		return;
	}

	while ( *stack ) {
		stack_pop( stack );
	}
}

/*********************************************************//**
 *
 ************************************************************/
void stack_print( Node **stack )
{
	if ( !stack ) {
		return;
	}
	if ( !*stack ) {
		puts( "<empty>\n" );
		return;
	}

	Node *walk = *stack;
	while ( walk ) {
		printf( "%d\n", walk->val );
		walk = walk->back;
	}
	putchar( '\n' );
}

/*********************************************************//**
 *
 ************************************************************/
int main( void )
{
	Node *stack1 = NULL, *stack2 = NULL;

	srand( time(NULL) );

	// fill stack1 with random ints in range [1,9999]
	for (int i=0; i < 15; i++ ) {
		stack_push( &stack1, 1 + rand() % 9999 );
	}
	puts( "Stack 1:" );
	stack_print( &stack1 );

	// move all elems of stack1 to stack2
	while ( stack1 ) {
		stack_push( &stack2, stack_pop( &stack1 ) );
	}
	
	puts( "Stack 1:" );
	stack_print( &stack1 );
	puts( "Stack 2:" );
	stack_print( &stack2 );

	stack_destroy( &stack2 );

	pressENTER()
	exit( EXIT_SUCCESS );
}
/*
Έξοδος:
Stack 1:
6357
6923
4794
5375
8659
9963
1836
4807
1588
2235
668
2254
9220
1583
9338

Stack 1:
<empty>

Stack 2:
9338
1583
9220
2254
668
2235
1588
4807
1836
9963
8659
5375
4794
6923
6357

press ENTER...
 */

 

  • Like 1
Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

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

Συχνή συμμετοχή στο θέμα

Δημοφιλείς Ημέρες

συναρτηση:

int rV(FILE * fp,TS *Elem){

return fscanf(from,"%d",Elem);

}

 

κληση 

if(!yperxeilisi) //to exw orisei se prohgoumenes grammes

      rV(from,Stoix);

 

to from einai orismeno san FILE *

kai to Stoix san TS * to opoio to ekana me typedef ...kai ousiastika einai int

Εφόσον έχεις δηλώσει ένα όρισμα fp και καλείς κιόλας την συνάρτηση ως rV(from,) τότε μέσα στην συνάρτηση έπρεπε να χρησιμοποιείς το fp. Επίσης το from πως το βλέπει η rV ? Είναι δηλωμένο globally ? Πέρα από αυτό, αν δεν έχεις σκοπό σε μετέπειτα στάδιο να εμπλουτίσεις την συνάρτηση, δεν έχει κάποιο νόημα έτσι όπως είναι. Κάλεσε κατευθείαν την fscanf από το if σου.

 

Επίσης, αν δεν σε αναγκάζει να χρησιμοποιείς typedefs η άσκηση, τότε απόφυγε τα. Το "TS *Elem" δεν προσφέρει τίποτα σε σχέση με το "int *Elem" και δυσκολεύει μάλιστα τον αναγνώστη αντί να τον ευκολύνει.

 

Τα παραπάνω βέβαια είναι γενικές συμβουλές και δεν έχουν σχέση με το λάθος που έχεις. Όσον αφορά εκείνο, το WinRAR υποστηρίζει κρυπτογράφηση. Έτσι δεν θα μπορούν συμφοιτητές σου να δουν τον κώδικά σου. Συμπίεσε τον κώδικά σου μαζί με όλα τα αρχεία εισόδου που χρησιμοποιείς και ανέβασε το αρχείο εδώ. Έπειτα στείλε με προσωπικό μήνυμα τον κωδικό σε όποιον θέλεις από τα παιδιά που συμμετέχουμε. Δεν είναι το ίδιο με το να τον ανεβάσεις χύμα εδώ ώστε να μπορούν να συμμετέχουν όλοι αλλά ίσως έτσι μπορέσει να βγάλει άκρη αυτός και σε βοηθήσει.

  • Like 1
Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Πάντως να ξέρεις ότι αν προσπαθήσεις να απομονώσεις ένα minimum example το οποίο εμφανίζει το πρόβλημα που σου παρουσιάζεται, πιθανά θα μπορέσεις και να το λύσεις.

 

Διάβασε εδώ για τα minimum working examples. Αναφέρεται σε LaTeX αλλά δεν αλλάζει κάτι όσον αφορά το σκοπό και τη χρησιμότητά του.

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Η μαντεψιά μου είναι πως το TS σημαίνει "Top of Stack" αλλά δεν μπορώ να ξέρω αν αναφέρεται σε κόμβο ή στο data field του κόμβου. Ανάλογα με το που αναφέρεται, αλλάζει και η υλοποίηση.

 

Επίσης, επειδή η φίλη μας λέει πως έκανε typedef int TS; υποθέτω πως τους έχει δοθεί κάποιου είδους ημι-generic stack implementation βασισμένο στο TS, και τους έχουν πει να κάνουν typedef το TS σε όποιον τύπο δεδομένων θέλουν να διαχειρίζονται με την στοίβα (σε int αυτή την περίπτωση).

 

Χωρίς περαιτέρω πληροφορίες είναι αδύνατον να ξέρουμε τι γίνεται. Συν ότι μια στοίβα μπορεί να οριστεί με παραπάνω του ενός τρόπου. Αν πάντως το TS αναφέρεται στον τύπο του data-field του κόμβου και όχι στον ίδιον τον κόμβο, τότε μια πιθανή ημι-generic υλοποίηση βασισμένη στον κώδικα του προηγούμενου ποστ μου που δουλεύει μονάχα με primitive τύπους (με γνωστό δηλαδή size) θα μπορούσε να είναι κάπως έτσι...

 

Κώδικας (stack.h - αντί για TS έχω Data)

 

 

#ifndef STACK_H
#define STACK_H

typedef int Data;
#define POP_SENTINEL -1

typedef struct node {
	Data data;
	struct node *back;
}Stack;

extern void stack_push( Stack **stack, Data data );
extern Data stack_pop( Stack **stack );
extern void stack_destroy( Stack **stack );
extern void stack_print( Stack **stack, void (*print_data)(Data data) );

#endif

 

Κώδικας (stack.c)

 

 

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

#include "stack.h"

/*********************************************************//**
 *
 ************************************************************/
void stack_push( Stack **stack, Data data )
{
	if ( !stack ) {
		fputs( "*** internal error (NULL pointer argument)!\n", stderr );
		return;
	}

	Stack *node = malloc( sizeof(Stack) );
	if ( !node ) {
		fputs( "*** malloc() failed!\n", stderr );
		return;
	}

	node->data = data;
	node->back = *stack;
	*stack = node;
}

/*********************************************************//**
 *
 ************************************************************/
Data stack_pop( Stack **stack )
{
	if ( !stack || !*stack ) {
		return POP_SENTINEL;
	}

	Data ret = (*stack)->data;
	Stack *back = (*stack)->back;
	free( *stack );
	*stack = back;

	return ret;
}

/*********************************************************//**
 *
 ************************************************************/
void stack_destroy( Stack **stack )
{
	if ( !stack || !*stack ) {
		return;
	}

	while ( *stack ) {
		stack_pop( stack );
	}
}

/*********************************************************//**
 *
 ************************************************************/
void stack_print( Stack **stack, void (*print_data)(Data data) )
{
	if ( !stack ) {
		puts( "<NULL>\n" );
		return;
	}
	if ( !*stack ) {
		puts( "<empty>\n" );
		return;
	}

	Stack *walk = *stack;
	while ( walk ) {
		print_data( walk->data );
		walk = walk->back;
	}
	putchar( '\n' );
}

 

Αλλάζοντας στο stack.h το typedef του Data, θα πρέπει να αλλαχτεί αντίστοιχα και η τιμή του POP_SENTINEL (είναι η τιμή που θέλουμε να επιστρέφει η stack_pop() όταν η στοίβα είναι άδεια).

 

Επίσης, η stack_print() παίρνει ως τελευταίο όρισμα ένα δείκτη στη συνάρτηση εκτύπωσης του εκάστοτε Data (και που προφανώς την ορίζουμε στο κεντρικό πηγαίο αρχείο).

 

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

 

Κώδικας (test.c)

 

 

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

#include "stack.h"

#define pressENTER()								\
	do{									\
		int c;								\
		printf( "press ENTER..." );					\
		while ( '\n' != (c=getchar()) && EOF != c )			\
			;							\
	}while(0)


/*********************************************************//**
 * Callback function to be passed to stack_print()
 ************************************************************/
void stack_print_node_data( Data data )
{
	printf( "%d\n", data );
}

/*********************************************************//**
 *
 ************************************************************/
int main( void )
{
	FILE *fp = NULL;
	char *fname = "from.txt";

	Stack *stack1 = NULL;
	Stack *stack2 = NULL;

	srand( time(NULL) );

	// create a file with 15 random ints in the range [1,9999]
	fp = fopen( fname, "w" );
	if ( !fp ) {
		fputs( "*** file write-error\n", stderr );
		exit( EXIT_FAILURE );
	}
	for (int i=0; i < 15; i++) {
		fprintf( fp, "%d ", 1 + rand() % 9999 );
	}
	fclose( fp );
	
	// read all ints from file into stack1
	fp = fopen( fname, "r" );
	if ( !fp ) {
		fputs( "*** file read-error\n", stderr );
		exit( EXIT_FAILURE );
	}
	for (; {
		int temp; 
		if ( 1 != fscanf( fp, "%d", &temp) ) {
			break;
		}
		stack_push( &stack1, temp );
	}
	fclose( fp );

	puts( "Stack 1:" );
	stack_print( &stack1, stack_print_node_data );

	// move all elems of stack1 to stack2
	while ( stack1 ) {
		stack_push( &stack2, stack_pop( &stack1 ) );
	}
	
	puts( "Stack 1:" );
	stack_print( &stack1, stack_print_node_data );
	puts( "Stack 2:" );
	stack_print( &stack2, stack_print_node_data );

	stack_destroy( &stack2 );

	pressENTER();
	exit( EXIT_SUCCESS );
}

 

gcc stack.c test.c
ΥΓ1. Αν το TS αναφέρεται στον κόμβο (και όχι στο data-field του) τότε χρειάζεται να ξέρουμε κι άλλες πληροφορίες από την εκφώνηση.

 

ΥΓ2. Για πραγματικά generic υλοποίηση στοίβας, ένα ενδεχόμενο είναι να χρησιμοποιηθεί void * αντί για Data, αλλά εκεί θα πρέπει να αντικατασταθούν αρκετά = με memcpy(), καθώς και να περνιέται ως όρισμα και το μέγεθος του εκάστοτε τύπου (βασικά, αλλάζει όλη η υλοποίηση). Ένα άλλο ενδεχόμενο generic υλοποίησης είναι να γίνουν όλα στον προεπεξεργαστή.

 

EDIT:

 

Εφόσον έχεις δηλώσει ένα όρισμα fp και καλείς κιόλας την συνάρτηση ως rV(from,) τότε μέσα στην συνάρτηση έπρεπε να χρησιμοποιείς το fp. Επίσης το from πως το βλέπει η rV ? Είναι δηλωμένο globally ?

...

Σωστός, τόσοι νοματαίοι χτες βράδυ, κανείς μας δεν το πρόσεξε αυτό!

 

...

Όσον αφορά εκείνο, το WinRAR υποστηρίζει κρυπτογράφηση. Έτσι δεν θα μπορούν συμφοιτητές σου να δουν τον κώδικά σου. Συμπίεσε τον κώδικά σου μαζί με όλα τα αρχεία εισόδου που χρησιμοποιείς και ανέβασε το αρχείο εδώ. Έπειτα στείλε με προσωπικό μήνυμα τον κωδικό σε όποιον θέλεις από τα παιδιά που συμμετέχουμε. Δεν είναι το ίδιο με το να τον ανεβάσεις χύμα εδώ ώστε να μπορούν να συμμετέχουν όλοι αλλά ίσως έτσι μπορέσει να βγάλει άκρη αυτός και σε βοηθήσει.

Κατά τη δική μου άποψη αυτό, παρότι θεμιτό, δεν συνάδει με το γενικότερο κλίμα ενός δημόσιου φόρουμ. Μπορεί να είναι δικιά μου παραξενιά, αλλά προσωπικά ενοχλούμαι όταν μου στέλνουν p.m. για τέτοιες περιπτώσεις. Συνήθως τους προτρέπω να το ποστάρουν δημόσια, ώστε και πιο γρήγορα ενδεχομένως να βρεθεί λύση και να επωφεληθούν και όσοι άλλοι έχουν το ίδιο πρόβλημα. Το καλύτερο από όλα, imho, είναι αυτό που είπε ο pmav99... να απομονώσουν το πρόβλημα και να το ποστάρουν.

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Κατά τη δική μου άποψη αυτό, παρότι θεμιτό, δεν συνάδει με το γενικότερο κλίμα ενός δημόσιου φόρουμ. Μπορεί να είναι δικιά μου παραξενιά, αλλά προσωπικά ενοχλούμαι όταν μου στέλνουν p.m. για τέτοιες περιπτώσεις. Συνήθως τους προτρέπω να το ποστάρουν δημόσια, ώστε και πιο γρήγορα ενδεχομένως να βρεθεί λύση και να επωφεληθούν και όσοι άλλοι έχουν το ίδιο πρόβλημα. Το καλύτερο από όλα, imho, είναι αυτό που είπε ο pmav99... να απομονώσουν το πρόβλημα και να το ποστάρουν.

 

 

Είναι και δική μου παραξενιά.

Και ώρες-ώρες το κακό με τα pm παραγίνεται...

Κι άντε να αποδείξεις ότι θέλεις μεν να βοηθήσεις, απλά όχι έτσι.

  • Like 2
Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Παιδιά τρέχει...πρόβλημα στην μνήμη ήταν τελικά!
διορθώθηκε!

Ευχαριστώ πολύ για τις συμβουλές
και συγγνώμη για την όποια αναστάτωση!  :-D

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

 

Θέλω να κάνουμε ένα κοινωνικό πείραμα. Να φτιάξει η kal03, με άλλο username, νέο thread και να πει ότι είναι άντρας. Αν πιάσει τις 2 σελίδες το thread, γίνομαι ιερέας. :3

 

  • Like 3
Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

 

Θέλω να κάνουμε ένα κοινωνικό πείραμα. Να φτιάξει η kal03, με άλλο username, νέο thread και να πει ότι είναι άντρας. Αν πιάσει τις 2 σελίδες το thread, γίνομαι ιερέας. :3

 

 Καταρήφθηκε (με 6 σελίδες).

  • Like 1
Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

 

Θέλω να κάνουμε ένα κοινωνικό πείραμα. Να φτιάξει η kal03, με άλλο username, νέο thread και να πει ότι είναι άντρας. Αν πιάσει τις 2 σελίδες το thread, γίνομαι ιερέας. :3

 

Οτι εχει να κανει με απλουστατη c, γινεται hot.

  • Like 2
Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Θέλω να κάνουμε ένα κοινωνικό πείραμα. Να φτιάξει η kal03, με άλλο username, νέο thread και να πει ότι είναι άντρας. Αν πιάσει τις 2 σελίδες το thread, γίνομαι ιερέας. :3

Γρήγορα να πας να γραφτείς για ιερέας :P

 

Οτι εχει να κανει με απλουστατη c, γινεται hot.

Κατ' εμέ δεν είναι τόσο ότι είναι η kal03 είναι γυναίκα (που προσωπικά το username kal03 δεν μου δίνει να καταλάβω κάποιο φύλο) αλλά είναι αυτό που είπε ο παπί ότι ήταν εύκολη ερώτηση. Και λογικό δεν είναι ? Σε ποιο νήμα θα απαντήσει περισσότερος κόσμος ? Σε αυτό που είναι εύκολο και το γνωρίζουν 7000 άτομα ή σε κάποιο που πρέπει να πρηχτείς και να χάσεις τη μισή μέρα σου για να απαντήσεις ?

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Θέλω να ζητήσω δημόσια συγγνώμη από όλα τα μέλη του φόρουμ που ασχολήθηκαν με το παρόν θέμα και τον Ιούλιο στο μηχανογραφικό μου θα δηλώσω ως πρώτη επιλογή Link.png Site: αυτή την σχολή. 

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

 

 

 

Θέλω να ζητήσω δημόσια συγγνώμη από όλα τα μέλη του φόρουμ που ασχολήθηκαν με το παρόν θέμα και τον Ιούλιο στο μηχανογραφικό μου θα δηλώσω ως πρώτη επιλογή Link.png Site: αυτή την σχολή. 

Στην προτείνω ανεπιφύλακτα! Το πρόγραμμα σπούδων που προσφέρει είναι κλάσεις ανώτερο από αυτό πανεπιστημίων στην Αμερική. Ο παπάς που με βάφτισε ήταν αμερικάνος. :P

 

 

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε

Πρέπει να είστε μέλος για να αφήσετε σχόλιο

Δημιουργία λογαριασμού

Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!

Δημιουργία νέου λογαριασμού

Σύνδεση

Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.

Συνδεθείτε τώρα

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