jimisvog Δημοσ. 1 Ιανουαρίου 2013 Δημοσ. 1 Ιανουαρίου 2013 Καλησπερα στο φορουμ και Χρονια πολλα... Εχω μια ασκηση σε C που χρειαζεται να χρησιμοποιω δεικτες και δυναμικη αναθεση μνημης. Πρεπει το προγραμμα να καλει μια συναρτηση οπου η συναρτηση θα κανει συγκεκριμένη δουλεια.. Αυτο που θελω να ρωτησω για αρχη ειναι τι σημαινει οταν μπροστα απο την συναρτηση υπαρχει ο αστερισκος (*)? Δηλαδη μας δινει ετοιμο το ονομα της συναρτησης ετσι: int * biggerTable(int *old, int old_size, int new_size) Καταλαβαινω πως σαν ορισματα δεχεται τον πινακα old με δεικτη ετσι ωστε να τον τροποποιησει, και 2 ακεραια μεγεθη.. Μπροστα απο το ονομα της συναρτησης γιατι εχει ομως το αστερακι? Τι υποδειλωνει και πως εγω θα την καλεσω?
albNik Δημοσ. 1 Ιανουαρίου 2013 Δημοσ. 1 Ιανουαρίου 2013 Σημαίνει ότι αυτό που επιστρέφει δεν είναι int αλλά δείκτης σε int. Με προλαβες
migf1 Δημοσ. 1 Ιανουαρίου 2013 Δημοσ. 1 Ιανουαρίου 2013 Καλησπέρα και χρόνια πολλά. Ουσιαστικά σου λέει πως η συνάρτηση θα επιστρέφει τον μεγαλωμένο πίνακα old. Μιας και για να αλλάξεις το μέγεθος του πίνακα θα χρησιμοποιήσεις την realloc(), οπότε δεν είναι εγγυημένο πως ο δείκτης που θα σου επιστρέψει η realloc() θα δείχνει στην ίδια διεύθυνση που έδειχνε ο αρχικός δέικτης old (δες την τεκμηρίωση της realloc()) η συνάρτησή σου πρέπει να επιστρέφει τον δείκτη που επιστρέφει η realloc() και όχι τον αρχικό old που περνάς σαν όρισμα.
jimisvog Δημοσ. 1 Ιανουαρίου 2013 Μέλος Δημοσ. 1 Ιανουαρίου 2013 Καταλαβα... Και την καλεις καπως ετσι? *biggerTable(*A, old_size, new_size);
MitsakosGR Δημοσ. 1 Ιανουαρίου 2013 Δημοσ. 1 Ιανουαρίου 2013 Όχι. Απλά το επιστρεφόμενο αποτέλεσμα το περνάς σε ένα int* (το αστεράκι πάει στο int, όχι στην συνάρτηση). int * newTable = biggerTable(A, old_size, new_size); //Δεν βάζεις * στο Α για να περάσεις τον δείκτη του μονάχα και όχι τα περιεχόμενά του //και η επιστρεφόμενη τιμή είναι int * οπότε το αναθέτεις αντίστοιχα.
migf1 Δημοσ. 1 Ιανουαρίου 2013 Δημοσ. 1 Ιανουαρίου 2013 Την καλείς είτε με είτε χωρίς αστερίσκο, ανάλογα αν αυτό που επιστρέφει η συνάρτηση θέλεις να το αναθέσεις σε δείκτη ή σε μεταβλητή ίδιου τύπου με αυτό στο οποίο δείχνει ο δείκτης που επιστρέφει η συνάρτηση (*). Στην περίπτωσή σου, η λογική κλήση της συνάρτησης είναι η παρακάτω... arrInt= biggerTable(arrInt, old_size, new_size); (*) EDIT: Το κείμενο αναφέρεται στην γενική περίπτωση μιας συνάρτησης που επιστρέφει δείκτη σε int, ενώ ο κώδικας αναφέρεται στη δική σου περίπτωση που αφορά ειδικά πίνακα από int.
jimisvog Δημοσ. 3 Ιανουαρίου 2013 Μέλος Δημοσ. 3 Ιανουαρίου 2013 Ωραια.. Τωρα εχω δημιουργησει την συναρτηση που αυξανει το μεγεθος του πινακα.. Φτιαχνω μια επαναληψη για να δω το περιεχομενο των πινακων ομως μου εμφανιζει την θεση μνημης αυτων.. Τι κανω λαθος..? int *biggerTable(int *old, int old_size, int new_size){ int i; old = malloc ((new_size-old_size) *sizeof(int)); for (i=0;i<new_size;i++){ printf ("%d\n",&old[i]); } }
perpap Δημοσ. 3 Ιανουαρίου 2013 Δημοσ. 3 Ιανουαρίου 2013 Πρώτον,έχεις λάθος στη δέσμευση μεγαλύτερης μνήμης για τον πίνακα. Όχι μόνο δε δεσμεύεις περισσότερη μνήμη,αλλά προσπαθείς να κάνεις access μνήμη που βρίσκεται πέρα από τα όρια του old. Αυτό θα έχει αποτέλεσμα ή να φας segmentation fault ή να τυπώσεις "σκουπίδια". Για να λυθεί το πρόβλημα χρησιμοποιήσε τη realloc για να μεγαλώσεις το πίνακα σου. old = (int *)realloc (old,(new_size-old_size) * sizeof(int)); Σου εμφανίζει τη θέση μνήμης γιατί χρησιμοποιείς το τελεστή &, οποίος επιστρέφει τη διεύθυνση της μνήμης του old. Οπότε απλώς βγάλε το & Τέλος κάνε και ένα return old; αφού η συνάρτηση πρέπει να επιστρέφει το δείκτη προν το μεγαλύτερο πίνακα.
Star_Light Δημοσ. 3 Ιανουαρίου 2013 Δημοσ. 3 Ιανουαρίου 2013 Καλησπερα στο φορουμ και Χρονια πολλα... Εχω μια ασκηση σε C που χρειαζεται να χρησιμοποιω δεικτες και δυναμικη αναθεση μνημης. Πρεπει το προγραμμα να καλει μια συναρτηση οπου η συναρτηση θα κανει συγκεκριμένη δουλεια.. Αυτο που θελω να ρωτησω για αρχη ειναι τι σημαινει οταν μπροστα απο την συναρτηση υπαρχει ο αστερισκος (*)? Δηλαδη μας δινει ετοιμο το ονομα της συναρτησης ετσι: int * biggerTable(int *old, int old_size, int new_size) Καταλαβαινω πως σαν ορισματα δεχεται τον πινακα old με δεικτη ετσι ωστε να τον τροποποιησει, και 2 ακεραια μεγεθη.. Μπροστα απο το ονομα της συναρτησης γιατι εχει ομως το αστερακι? Τι υποδειλωνει και πως εγω θα την καλεσω? Ακομη και αν η παραμετρος old περνουσε μεσα με array notation old[] παλι δεικτης (με τιμή διευθυνση στο 1ο στοιχειο του πινακα σου) θα ηταν αυτο που θα περνουσε μεσα στην συναρτηση. Μεσα σε μια συναρτηση ενας πινακας αντιμετωπιζεται σαν δεικτης με την προυποθεση οτι τον εχεις δηλωσει στις παραμετρους της συναρτησης ειτε με μορφη πινακα ειτε με μορφη δεικτη. Ειναι πολυ σημαντικο να το ξεκαθαρισεις αυτο γιατι ειναι σημαντικοτερο απο αυτο που ρωτας
ZAKKWYLDE Δημοσ. 4 Ιανουαρίου 2013 Δημοσ. 4 Ιανουαρίου 2013 Ένα θεματάκι είναι να μάθεις να διαβάζεις τη σύνταξη στη C...το παρακάτω θα σε βοηθήσει να ξερεις τι ακριβώς είναι καθε declaration http://c-faq.com/decl/spiral.anderson.html
jimisvog Δημοσ. 4 Ιανουαρίου 2013 Μέλος Δημοσ. 4 Ιανουαρίου 2013 Ευχαριστω παιδια για τις απαντησεις.. Μου προέκυψε ομως ενα άλλο προβλημα.. Στην συναρτηση επεξεργαζομαι τον πινακα old και στο τελος κανω return old, ομως στο προγραμμα δινω την εντολη να εμφανισει τα περιεχομενα του "νεου" πλεον πινακα και μου γραφει: process exited with return value 3221225477 Ο κωδικας ειναι ο εξης: int *biggerTable(int *old, int old_size, int new_size){ int i, k; old = (int *)realloc (old,(new_size-old_size) *sizeof(int)); ... ... ... ... return old; int main() { ... ... ... ... biggerTable(A, old_size, new_size); for (i=0;i<(new_size);i++){ printf ("%d\n", A[i]); } return 0; } Γιατι δεν εμφανιζει τα στοιχεια του Α πλεον? :/
MitsakosGR Δημοσ. 4 Ιανουαρίου 2013 Δημοσ. 4 Ιανουαρίου 2013 Αν δεν κάνω λάθος η realloc δεν παίρνει σαν δεύτερο όρισμα την διαφορά των μεγεθών αλλά το καινούργιο μέγεθος. Οπότε δεν είναι old = (int *)realloc (old,(new_size-old_size) *sizeof(int)); αλλά old = (int *)realloc (old, new_size * sizeof(int));
Erevis Δημοσ. 4 Ιανουαρίου 2013 Δημοσ. 4 Ιανουαρίου 2013 Αν δεν κάνω λάθος η realloc δεν παίρνει σαν δεύτερο όρισμα την διαφορά των μεγεθών αλλά το καινούργιο μέγεθος. Οπότε δεν είναι old = (int *)realloc (old,(new_size-old_size) *sizeof(int)); αλλάold = (int *)realloc (old, new_size * sizeof(int)); Σωστός ο MitsakosGR, πόνεσαν τα μάτια μας πριν. Επίσης καλό θα ήταν να αποθηκεύσεις το αποτέλεσμα της realloc σε έναν άλλο temporary pointer, και μόνο αν η δέσμευση πετύχει να επιστρέψεις αυτόν, δηλαδή αν δεν επιστραφεί NULL από τη realloc. Σε περίπτωση που η realloc αποτύχει θα επιστρέφεις τον pointer που περάστηκε σαν όρισμα. Αυτό βέβαια έχει το άλλο κακό, πώς η συνάρτησή σου θα αποτύχει σιωπηρά, και γι'αυτό υπάρχουν δύο λύσεις. 1. Περνάς κάποιον int by reference στην συνάρτηση και επιστρέφεις σε αυτόν ένα status code που υποδεικνύει αν η συνάρτησή σου πέτυχε ή απέτυχε. Ακόμα καλύτερα: 2. Η συνάρτηση να επιστρέφει int με το status code και τον πίνακα που θες να κάνεις resize να τον περνάς στη συνάρτηση με διπλό pointer. Από τις δύο, συγκεκριμένα σ'εσένα θα πρότεινα την 1η, γιατί είσαι πολύ αρχάριος με τους pointers. Αλλά αν είσαι πολύ περιπετειώδης τύπος μπορείς να δοκιμάσεις τη 2η. Όλα αυτά χρειάζονται γιατί σε περίπτωση που αποτύχει η realloc, θα εκχωρήσεις NULL στον pointer που έδειχνε στον πίνακα (εκεί που θα κληθεί η συνάρτησή σου), και εκτός του ότι θα χάσεις τα δεδομένα του, θα έχεις και memory leak. Έσχατη λύση είναι να εκχωρείς το αποτέλεσμα της κλήσης της συνάρτησής σου σε temporary pointer και αν δεν είναι NULL να εκχωρείς αυτόν τον pointer σε αυτόν που έδειχνε στον πίνακα. Αυτό έχει το μειονέκτημα πως θα πρέπει να γίνεται ΚΑΘΕ φορά που την καλείς.
jimisvog Δημοσ. 4 Ιανουαρίου 2013 Μέλος Δημοσ. 4 Ιανουαρίου 2013 Να απτυχει η realloc ειναι λιγο δυσκολο στην συγκεκριμενη περιπτωση γιατι δινονται τα νουμερα στανταρ απο πριν.. (π.χ στην main τα μεγεθη old_size και new_size παιρνουν συγκεκριμενους αριθμους) οποτε εμενα το μονο μου προβλημα ειναι γιατι δεν κανει print αυτα που θελω στην main.. EDIT: Ακυρο.. Τελικα το προβλημα ηταν με την συνταξη της realloc.. Προφανως με την διορθωση αυτη διορθωθηκε και το προβλημα.. ΕΥΧΑΡΙΣΤΩ ολους για την πολυτιμη βοηθεια..
Προτεινόμενες αναρτήσεις
Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε
Πρέπει να είστε μέλος για να αφήσετε σχόλιο
Δημιουργία λογαριασμού
Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!
Δημιουργία νέου λογαριασμούΣύνδεση
Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.
Συνδεθείτε τώρα