Δημοσιεύτηκε: 08 Σεπ 2011, 14:51
από migf1
Πετάχτηκα μέχρι την τράπεζα, λοιπόν...

Star_Light έγραψε:
migf1 έγραψε:
......

Αν ελέγξουμε πρώτα το περιεχόμενο του δείκτη ( *src == '\0 ') τότε αν ο src είχε για παράδειγμα περαστεί με τιμή NULL στην συνάρτηση, έστω και κατά λάθος, τότε προκαλούμε segmentation-fault (και άρα κενό ασφαλείας) διότι NULL σημαίνει πως δείχνει στο ΠΟΥΘΕΝΑ (που στην πράξη σημαίνει πως δείχνει σε κάποιο τυχαίο σημείο της μνήμης ... undefined ). Οπότε, γράφοντας εμείς *src == '\0' ρισκάρουμε να μετατραπεί κάποια στιγμή στο run-time του προγράμματος σε *NULL == '\0'... κι εκεί αρχίζουν τα όργανα! :lol:

......



Eρωτήσεις :

1.Κάθε string της μορφής s1[]=""; ειναι κενό? Υπαρκτό μεν κενο δε... υπαρκτό επειδη φέρει τον μηδενικο χαρακτήρα ετσι?

Υπαρκτό επειδή έχει δεσμευτεί έγκυρη μνήμη για αυτό (αυτόματα, λόγω το ορισμού του με σύνταξη πινάκων :) ) Επίσης, ναι μπορούμε να το θεωρήσουμε ως κενό string επειδή ο 1ος του χαρακτήρας είναι ο μηδενικός (με γενική ορολογία πινάκων όμως δεν είναι κενό, έχει ένα στοιχείο στη 1η του θέση, τον μηδενικό χαρακτήρα).

έγραψε:2. Μπορεις να δώσεις ενα παράδειγμα απο ενα ανύπαρκτο string???

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

char *string = NULL; // έγκυρο αλλά ανύπαρκτο γιατί δεν έχει δείχνει σε υπαρκτά περιεχόμενα, δεν έχει καν περιεχόμενα
char *string; // υπαρκτό αλλά άκυρο, γιατί δείχνει άκυρα περιεχόμενα (περιεχόμενα για τα οποία δεν έχουμε την παραμικρή ιδέα ποια είναι και που βρίσκονται)
char *string = calloc(100, sizeof(char) ); // υπαρκτό κι έγκυρο, με τα περιεχόμενά του να αποτελούνται από 100 μηδενικούς χαρακτήρες


έγραψε:3. Εδω μπερδεύομαι λιγο γιατι ειχαμε πει πως σε απροσδιόριστη περιοχή δείχνουν μονο οι άκυροι δείκτες ενω ενας δείκτης ο οποίος δειχνει σε NULL δεν εχει μεν περιεχομενα αλλα ειναι έγκυρος.

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

Το καλύτερο από όλα είναι να κρατήσετε πως όταν ορίζετε δείκτες πρέπει να τους αρχικοποιείτε άμεσα (με calloc() ή σε NULL) και να ελέγχετε αν είναι NULL πριν τους απελευθερώσετε με free() κι αμέσως μετά να τους αναθέτετε την τιμή NULL.

έγραψε:4. Αν τα ορίσματα ήταν απλοί πίνακες (ωστε να εξασφαλίσουμε οτι καταρχην δεν θα μας άφηνε να δωσουμε NULL ουτε και κατα λαθος και επισης πως η ομαλή δέσμευση γίνεται αυτόματα) τοτε θα υπήρχε και διαφορά οταν θα τα βάζαμε σαν ορίσματα στην συνάρτηση??? θελω να πω δεν θα τα περνουσαμε ως δείκτες ετσι... αλλα παιζει να ειναι και περιττη αυτη η ερωτηση μιας και το λες και ο ιδιος οτι δεν θα τα διαχειριστουμε ως δεικτες.

Μπορούμε να τα περάσουμε και ως δείκτες, δεν υπάρχει πρόβλημα.

έγραψε:
5. Όταν δηλώνεις εναν δεικτη απλα πχ
Κώδικας: Επιλογή όλων
int *p;


περα απο το οτι δεν ειναι αρχικοποιημενος... δεν δεσμεύεται μνήμη για αυτον? Πρεπει αναγκαστικά να δωσεις calloc για να γινει έγκυρη αυτη η μνήμη? ΔΗλαδη ας πουμε αν ορισω εγω εναν δεικτη ουσιαστικα θα έχει απλα το προκαθορισμενο μέγεθος που είπαμε ειναι ιδιο για ολα τα data types χωρις αυτο να σημαινει πχ οτι τον έχω δεσμεύσει ωστε να μπορει να δείχνει για 10 θέσεις ας πουμε αν εγω πιο μετα σε ενα while τον αυξάνω με αριθμητικη δεικτων ε?

Ακριβώς!

έγραψε:6. ΣΤο παρακατω απόσπασμα κώδικα

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

if (src)
{
free(src);
src=NULL;
}


Το if(src) ειναι ισοδυναμο με το if(src!==NULL)
ενω το *src!=0 θα ίσχυες αν το string δεν ηταν κενό ?

To if ( src ) εξασφαλίζει πως ο src έχει κάποια περιεχόμενα (δεν είναι NULL δηλαδή)... και άρα μπορείς κατόπιν να ελέγξεις αυτά τα περιεχόμενα, που ξεκινάνε με *src. Το να είναι έγκυρα όμως αυτά τα περιεχόμενα πρέπει να το έχεις εξασφαλίσει εσύ πριν φτάσεις στο if ( src ).

Η οποιαδήποτε ενέργεια που εμπλέκει το *src πρέπει να είναι πάντα είναι το επόμενο στάδιο μετά το if ( src ) και ποτέ προηγούμενο.

Ο όρος "κενό" για το περιεχόμενο του src είναι σχετικός, όπως εξήγησα παραπάνω στην απάντηση Νο.1