IkaroC Δημοσ. 24 Ιανουαρίου 2013 Δημοσ. 24 Ιανουαρίου 2013 καλησπερα!θα ηθελα να ρωτησω καποια πραγματα πανω στην c.ειμαι στο κεφαλαιο με τους δεικτες και κατανομη μνημης.αυτο που δεν καταλαβαινω ειναι η τοσο τρομερη σημασια της συναρτησης malloc!!το βιβλιο λεει οτι ειναι πολυ πιο χρησιμο να χρησιμοποιησεις malloc απο το να δειλωσεις εναν πινακα π.χ. διοτι με τον πινακα καταλαμβανεις πολυ περισσοτερη μνημη!τωρα εγω με την λογικη μου λεω οτι ειτε πινακα δηλωσεις ειτε χρησιμοποιησεις malloc..παντα τηα πρεπει να ξερεις τα bytes που δεσμευεις!δηλαδη--->char input[81];puts("enter text");gets(input);ή --->char *ptrptr=malloc(81 * sizeof(char)));puts("enter text");gets(ptr);και στις δυο περιπτωσεις εχω πιασει χωρο 81bytes!!μπορει να εχω κανει καποια λαθη στον παραπανω κωδικα,παρακαλω διορθωστε με..αρχη ειναι ακομα
bird Δημοσ. 24 Ιανουαρίου 2013 Δημοσ. 24 Ιανουαρίου 2013 Για αρχή σκέψου όταν δεν ξέρεις τον αριθμό των στοιχείων που θέλεις να έχει ένας πίνακας θα πρέπει αρχικά να δηλώσεις έναν πολύ μεγάλο πίνακα ώστε να είσαι σίγουρος οτι θα χωρέσουν όλα μέσα, ή θα έχεις κάποιον περιορισμό στο πόσα στοιχεία θα διαβάσεις. (σε αυτή την περίπτωση αν εχεις δεσμεύσει 100 στοιχεια στον πίνακα και χρησιμοποιήσεις μόνο τα 50, έχεις δεσμευμένη μνήμη που είναι άχρησητη). Με την malloc, δεσμευείς ακριβώς όση μνήμη χρειάζεσαι κάθε φορά (χωρίς να κάνεις σπατάλη) και μπορείς να την αποδεσμεύεις επίσης ανά πάσα στιγμή με τη free, πράγμα που δεν μπορείς να κάνεις με τους πίνακες, οι οποίοι σου κράτανε την μνήμη γιά όσο τρέχει το πρόγραμμα... 1
IkaroC Δημοσ. 24 Ιανουαρίου 2013 Μέλος Δημοσ. 24 Ιανουαρίου 2013 Με την malloc, δεσμευείς ακριβώς όση μνήμη χρειάζεσαι κάθε φορά (χωρίς να κάνεις σπατάλη) και μπορείς να την αποδεσμεύεις επίσης ανά πάσα στιγμή με τη free, πράγμα που δεν μπορείς να κάνεις με τους πίνακες, οι οποίοι σου κράτανε την μνήμη γιά όσο τρέχει το πρόγραμμα... Αυτη ακριβως ειναι η απορια μου!πως θα ξερω ποση ακριβως μνημη χρειάζεται κάθε φορά με την malloc? αφου ο χρηστης καθε φορα θα πληκτρολογει κατι διαφορετικο! η malloc οπως γραφω συντασεται:ptr=malloc(x * sizeof(char)));....στην θεση του x πρεπει να ξερω απο πριν ποση μνημη πρεπει να δεσμευσω! αρα οταν γραφω τον κωδικα θα πρεπει να εχω βαλει ηδη μια τιμη στο x!
pmav99 Δημοσ. 24 Ιανουαρίου 2013 Δημοσ. 24 Ιανουαρίου 2013 Σκέψου την περίπτωση το x να είναι μεταβλητή (πχ να το δίνει ο χρήστης). Τότε, με τη malloc κάθε φορά που θα τρέχει το πρόγραμμα θα δεσμεύεται ακριβώς η μνήμη που χρειάζεσαι και όταν δεν θα τη χρειάζεσαι ποια, θα μπορείς να την αποδεσμεύεις με την free.
Directx Δημοσ. 24 Ιανουαρίου 2013 Δημοσ. 24 Ιανουαρίου 2013 Αυτη ακριβως ειναι η απορια μου!πως θα ξερω ποση ακριβως μνημη χρειάζεται κάθε φορά με την malloc? αφου ο χρηστης καθε φορα θα πληκτρολογει κατι διαφορετικο! η malloc οπως γραφω συντασεται:ptr=malloc(x * sizeof(char)));....στην θεση του x πρεπει να ξερω απο πριν ποση μνημη πρεπει να δεσμευσω! αρα οταν γραφω τον κωδικα θα πρεπει να εχω βαλει ηδη μια τιμη στο x! Ιδανικά μπορείς να χρησιμοποιήσεις την realloc η οποία επιτρέπει την αύξηση ή την σμίκρυνση του buffer σου κατά το δοκούν, αυξάνοντας ή σμικρύνοντας τον με βάση τα πλήκτρα που πατάει ο χρήστης αλλά καθώς στην στάνταρτ C δεν έχουμε συγκεκριμένες συναρτήσεις που να διαβάζουν το πληκτρολόγιο σε επίπεδο κωδικού-πλήκτρου, scan-code δηλαδή (ώστε να πιάνουμε πότε ο χρήστης πάτησε το πλήκτρο "DEL" για παράδειγμα ή σε ποίο σημείο βρίσκεται ο κέρσορας του εντός του αλφαριθμητικού κλπ) η χρήση της realloc δεν βοηθάει επί του προκείμενου. Συνεπώς, για το πρόβλημα που αναφέρεις η πιο συνηθισμένη λύση είναι η δέσμευση ενός αρκετά μεγάλου buffer (μεγέθους σταθεράς BUFSIZ που σε μερικούς compiler είναι και ο μέγιστος αριθμός χαρακτήρων που μπορεί να διαβάσει ανά γραμμή η κονσόλα) και η ανάγνωση σε αυτό, δίχως πολλά - πολλά. πχ. #include <stdio.h> char *buff = NULL; int main(void) { if((buff = malloc(BUFSIZ))) { if(fgets(buff, BUFSIZ, stdin)) puts(buff); free(buff); } return 0; } ή #include <stdio.h> int main(void) { char buff[BUFSIZ]; if(fgets(buff, BUFSIZ, stdin)) puts(buff); return 0; }
IkaroC Δημοσ. 24 Ιανουαρίου 2013 Μέλος Δημοσ. 24 Ιανουαρίου 2013 δηλαδη οταν το προγραμ Σκέψου την περίπτωση το x να είναι μεταβλητή (πχ να το δίνει ο χρήστης). Τότε, με τη malloc κάθε φορά που θα τρέχει το πρόγραμμα θα δεσμεύεται ακριβώς η μνήμη που χρειάζεσαι και όταν δεν θα τη χρειάζεσαι ποια, θα μπορείς να την αποδεσμεύεις με την free. Δηλαδη αμα εχω ενα προγραμμα που καλειται να διαβαζει μια ακολουθεια χαρακτιρων απο το χρηστη...θα πρεπει να του ζηταω να μου λεει τον αριθμο των χαρακτηρων της προτασης του και αυτον τον αρηθμο να τον αποθηκευω στην πεταβλητη χ? Ειναι λιγο χαζο αυτο..θα βαζω τον χρηστη να πετραει τα γραμματα της προτασης του?
ZAKKWYLDE Δημοσ. 24 Ιανουαρίου 2013 Δημοσ. 24 Ιανουαρίου 2013 Θα ζητάς απο τον χρήστη παράδειγμα "Πόσο μεγάλο πίνακα θέλεις" και θα αποθηκεύεις τη τιμή στο x. Αν ο χρήστης σου δώσει π.χ. 5 ο η malloc θα γίνει malloc(5*sizeof(char)). Βέβαια αν θέλεις να ξανα-αλλάξεις τον πίνακα θέλεις realloc. Σε τέτοια περίπτωση όμως θα έλεγα απλά να γράψεις ένα ArrayList να τελειώνεις δηλαδη οταν το προγραμ Δηλαδη αμα εχω ενα προγραμμα που καλειται να διαβαζει μια ακολουθεια χαρακτιρων απο το χρηστη...θα πρεπει να του ζηταω να μου λεει τον αριθμο των χαρακτηρων της προτασης του και αυτον τον αρηθμο να τον αποθηκευω στην πεταβλητη χ? Ειναι λιγο χαζο αυτο..θα βαζω τον χρηστη να πετραει τα γραμματα της προτασης του? Σε αυτή τη περίπτωση είναι χαζό. Ας πούμε όμως ότι υπάρχει περίπτωση να ξέρει σίγουρα ο χρήστης πόσες θέσεις χρειάζεται. Μπορεί για παράδειγμα να είχες να κάνεις εγγραφές πελατών. Θα ρώταγες πόσους θέλεις να εισάγεις; 3 ξέρω γω. Εκεί θα είχε νόημα. Στη περίτπωσή σου που δεν ξέρεις τι θα εισάγει ο άλλος πρέπει να μάθεις τι είναι το ArrayList και ενδεχομένως το LinkedList.
IkaroC Δημοσ. 24 Ιανουαρίου 2013 Μέλος Δημοσ. 24 Ιανουαρίου 2013 Ναι καταλαβα τι λες! Αμα δηλωσω εναν δεικτι char *k και πω στον χρηστη να πληκτρολογησει το μημυμα του π.χ. puts("enter text:); gets(k); puts(k); στον δεικτη κ θα αποθηκευτει η θεση του πρωτου γραμματος του μηνυματος και με την puts(k) θα εκτυπωσει απο το πρωτο γραμμα μεχρι τον κενο χαρακτιρα("\0") αυτο θα δουλευε?????
bird Δημοσ. 24 Ιανουαρίου 2013 Δημοσ. 24 Ιανουαρίου 2013 Ναι καταλαβα τι λες! Αμα δηλωσω εναν δεικτι char *k και πω στον χρηστη να πληκτρολογησει το μημυμα του π.χ. puts("enter text:); gets(k); puts(k); στον δεικτη κ θα αποθηκευτει η θεση του πρωτου γραμματος του μηνυματος και με την puts(k) θα εκτυπωσει απο το πρωτο γραμμα μεχρι τον κενο χαρακτιρα("\0") αυτο θα δουλευε????? Για να μπορέσεις η gets να αποθηκευσει το string θα πρέπει ο k να δείχνει σε ένα κομμάτι δεσμευμένης μνήμης. Πρώτα πρέπει να κάνεις malloc και μετά να καλέσεις την gets Γενικά όμως υπάρχουν διάφορες λύσεις για το πώς να χρησιμοποιείς την malloc χωρίς να χρειάζεται να ρωτήσεις τον χρήστη από πρίν πόσα στοιχεια έχει σκοπό να δώσει.
ZAKKWYLDE Δημοσ. 24 Ιανουαρίου 2013 Δημοσ. 24 Ιανουαρίου 2013 Μπορείς να χρησιμοποιήσεις και την fgets όπου βάζεις και limit στους χαρακτήρες που θα διαβάσει. π.χ char k[51]; //50 + 1 to \0 fgets(k, 50, stdin); //to stdin είναι το standard input σου(το πληκτρολόγιο δλδ).
IkaroC Δημοσ. 24 Ιανουαρίου 2013 Μέλος Δημοσ. 24 Ιανουαρίου 2013 ευχαριστω πολυ παιδια για τις απαντησεις! ξεκαθαρισα αρκετα πραγματα που τα ειχα καταλαβει λαθος
Προτεινόμενες αναρτήσεις
Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε
Πρέπει να είστε μέλος για να αφήσετε σχόλιο
Δημιουργία λογαριασμού
Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!
Δημιουργία νέου λογαριασμούΣύνδεση
Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.
Συνδεθείτε τώρα