Δημοσιεύτηκε: 05 Σεπ 2011, 17:13
από Star_Light
migf1 έγραψε:Καλημέρα,

...

Θα μπορούσε, με την έννοια πως ο compiler δεν θα παραπονιόταν, αλλά όταν έτρεχες το πρόγραμμα θα έδινε segmentation fault στο συγκεκριμένο σημείο.

Είναι δηλαδή δική σου ευθύνη να εξασφαλίσεις είτε ότι δεν θα ζητήσεις να διαβάσεις από την κύρια είσοδο το παραπάνω string, είτε πως αν το ζητήσεις τότε να έχεις εξασφαλίσει πως το έχεις ορίσει να χωράει τουλάχιστον το ελάχιστο πλήθος χαρακτήρων + τον μηδενικό για τις ανάγκες του προγράμματος σε εκείνο το σημείο.


Ok! :)
migf1 έγραψε:
Στον 9ο χαρακτήρα ( username[8] ) πρέπει να έχει το '\0' ώστε να σηματοδοτείται το τέλος του τρέχοντος μήκους του και στη συνέχεια μέχρι και τον χαρακτήρα username[31] μπορεί να έχει οτιδήποτε ... ιδανικά όλο μηδενικούς χαρακτήρες.

Το buffer σου στο συγκεκριμένο παράδειγμα είναι 32 συνεχόμενα bytes στη μνήμη (32 χαρακτήρες) οπότε όσο αναφέρεσαι σε αυτό μένοντας εντός ορίων του δεν έχεις υπερχείλιση (ούτε άνω, ούτε κάτω).

Ίσως είχες διαβάσει κάτι άλλο, ή με άλλα συμφραζόμενα, δεν ξέρω. Ίσως διάβασες πως αν δεν γεμίσεις ότι περισσεύει μέχρι τον 32ο χαρακτήρα με '\0' τότε ρισκάρεις σε εκείνο τον χώρο να βάλουν χάκερς δικό τους κώδικα ;) Για αυτό και όταν ορίζετε strings να τα αρχικοποιείται ΠΑΝΤΑ με μηδενικούς χαρακτήρες σε όλο το μέγιστο μήκος τους!

Ισως να παρανόησα εγω.... Ευχαριστω για να παω να το διορθωσω στον οδηγο που ειχα φτιαξει για το buffer overflow αν θες ριξτου και εσυ μια ματια (φυσικα ειναι πολυ εισαγωγικος δεν προσεγγιζω καν το θεμα στον πυρηνα του αλλα για να εχει μια ιδεα κάποιος) καθως αν εχω γραψει κάποια μπουρδα θα την διορθωσεις!!!! Βεβαια ακομη με προβληματιζει διοτι και αυτο που ειχα διαβασει για 8 χαρακτηρες ονοματα ισως και να μην ισχυει διοτι πχ το δικο μου hostname ειναι παραπανω πχ

Κώδικας: Επιλογή όλων
kostas@kostas-SSL:~$ hostname
kostas-SSL
kostas@kostas-SSL:~$


εκτος βεβαια και αν εννοει το kostas απο τα αριστερα και οχι το kostas μαζι με το SSL απο την αλλη που ειναι γενικα το hostname και οχι το username :)

migf1 έγραψε:
Χοντρικά, και μόνο για τα strings μιας και κάθε στοιχείο τους είναι 1 byte (1 χαρακτήρας) τρέχον μήκος είναι η τιμή που επιστρέφει η strlen( s ) και μέγιστο μήκος είναι η τιμή που επιστρέφει η sizeof( s ) (με την προϋπόθεση πως το s έχει οριστεί ως string και όχι ως string literal).

Κώδικας: Επιλογή όλων

char s[10] = "abc"; // strlen( s ) = 3, sizeof( s ) = 10




αααα οκ ναι το ειχες εξηγησει και παλαιοτερα τωρα καταλαβα! Αν ειχε οριστει σαν string literal θα ηταν char s[3]="abc"; ???

migf1 έγραψε:
Αν συμφωνήσουμε όμως πως κατά βάση τα strings είναι πίνακες χαρακτήρων, τότε λέγοντας δείκτης σε string είναι σαν να λέμε δείκτης σε πίνακα χαρακτήρων. Μιλάμε δηλαδή για διπλό δείκτη και όχι για μονό ;)

migf1 έγραψε:
Σε high-level γλώσσες (π.χ. python) δεν θέλει τόσο ψείρισμα, γιατί εκείνες σου δίνουν έτοιμα πάρα πολλά πράγματα.

Π.χ.στη C++ εκτός από τον κλασικό τρόπο διαχείρισης των strings για τον οποίο συζητάμε εδώ, μπορείς εναλλακτικά να χρησιμοποιήσεις την κλάση string από στην στάνταρ βιβλιοθήκη της γλώσσας, οπότε όχι μόνο παύουν να σε απασχολούν τέτοιου είδους θέματα (τα τι & πως δηλαδή που συμβαίνουν στο παρασκήνιο), αλλά έχεις έτοιμη και μια διευρυμένη γκάμα από συναρτήσεις, τελεστές και δομές για τη διαχείριση των strings. Σε low-level γλώσσες όπως η C τέτοια λειτουργικότητα είτε πρέπει να την χτίσεις μόνος σου, είτε να τη βρεις έτοιμη αλλά σε ΜΗ στάνταρ βιβλιοθήκες (για τη C σχεδόν τα πάντα υπάρχουν έτοιμα, αλλά σε ΜΗ στάνταρ βιβλιοθήκες.... όπως π.χ. η μαθηματική βιβλιοθήκη mpfr που λέγαμε προχτές ;) )


πολυ ενδιαφερον!!!!! Eπισης ποια η διαφορα των στάνταρ απο τις μη στάνταρ βιβλιοθήκες της γλώσσας?