Τα πάντα για την C

...του ubuntu και έργων ΕΛ/ΛΑΚ (Έργα-Οδηγοί-Προτάσεις)

Συντονιστής: konnn

Re: Τα πάντα για την C

Δημοσίευσηαπό Ilias95 » 21 Μαρ 2012, 20:08

Ας ξεκινήσω με μια απορία.

Έχω ένα string και θέλω να αλλάξω το πρώτο του γράμμα (ουσιαστικά το πρώτο στοιχείο της array).
Πιθανότατα θα το έκανα έτσι:
Κώδικας: Επιλογή όλων
char str[] = "String";
str[0] = 'X';
puts(str);

Αν όμως δηλώσω το string έτσι:
Κώδικας: Επιλογή όλων
char *str = "String";

Πως θα κάνω το ίδιο πράγμα;

Σκέφτηκα να το κάνω έτσι:
Κώδικας: Επιλογή όλων
char *str = "String", *p = str;
*p = 'X';
puts(str);

Όμως παίρνω Segmentation fault χωρίς κανένα warning στο compile.

Πως θα το κάνω τελικά και γιατί το παραπάνω δεν δουλεύει;
Ilias95
saintTUX
saintTUX
 
Δημοσιεύσεις: 1548
Εγγραφή: 29 Απρ 2011, 23:26
Εκτύπωση

Re: Τα πάντα για την C

Δημοσίευσηαπό migf1 » 21 Μαρ 2012, 20:56

Όταν το αρχικοποιείς με διατύπωση δείκτη (*str = "abcd") αντί για διατύπωση πίνακα (str[] = "abcd") το κάνεις read-only, δηλαδή string literal... οπότε δεν μπορείς να το αλλάξεις ;)
Go under the hood with C: Pointers, Strings, Linked Lists
Άβαταρ μέλους
migf1
powerTUX
powerTUX
 
Δημοσιεύσεις: 2082
Εγγραφή: 03 Ιουν 2011, 16:32
Εκτύπωση

Re: Τα πάντα για την C

Δημοσίευσηαπό Ilias95 » 21 Μαρ 2012, 21:01

migf1 έγραψε:Όταν το αρχικοποιείς με διατύπωση δείκτη (*str = "abcd") αντί για διατύπωση πίνακα (str[] = "abcd") το κάνεις read-only, δηλαδή string literal... οπότε δεν μπορείς να το αλλάξεις ;)

Χμμ. Υπάρχει κάποιος συγκεκριμένος λόγος που γίνεται αυτό;

Γιατί ας πούμε ότι πάω να περιγράψω τι γίνεται στον κώδικα:
Κώδικας: Επιλογή όλων
char *str = "String", *p = str;
*p = 'X';
puts(str);

Ο pointer str δείχνει εκεί που είναι αποθηκευμένος ο χαρακτήρας 'S'. Βάζω τον pointer p να δείχνει στο ίδιο σημείο.
Αλλάζω το περιεχόμενο της μνήμης στο οποίο δείχνουν ο str και ο p σε 'X'.
Τέλος εκτυπώνω τους χαρακτήρες απ' τη διεύθυνση μνήμης όπου δείχνει ο str μέχρι να πετύχω NULL.

Που κάνω λάθος;
Ilias95
saintTUX
saintTUX
 
Δημοσιεύσεις: 1548
Εγγραφή: 29 Απρ 2011, 23:26
Εκτύπωση

Re: Τα πάντα για την C

Δημοσίευσηαπό migf1 » 21 Μαρ 2012, 21:18

Τα περιεχόμενα του str δεν μπορείς να τα πειράξεις, γιατί το έχεις αρχικοποιημένο ως read-only... αρχικοποίησέ το με διατύπωση πινάκων αν σκοπέυεις μελλοντικά να του αλλάξεις οποιονδήποτε χαρακτήρα του...

Μορφοποιημένος Κώδικας: Επιλογή όλων
char str[] = "String", *p = str;
Go under the hood with C: Pointers, Strings, Linked Lists
Άβαταρ μέλους
migf1
powerTUX
powerTUX
 
Δημοσιεύσεις: 2082
Εγγραφή: 03 Ιουν 2011, 16:32
Εκτύπωση

Re: Τα πάντα για την C

Δημοσίευσηαπό Ilias95 » 21 Μαρ 2012, 21:22

Ναι, το κατάλαβα ότι είναι immutable.
Το γιατί ρωτάω. Γιατί έτσι όπως το εξηγώ μου ακούγεται σωστό. :P
Στην παραπάνω εξήγηση που δίνω, στο γιατί θεωρώ ότι κανονικά θα άλλαζε το string λέω κάτι λάθος;

Ίσως να μην έχει ιδιαίτερη σημασία όμως. Anyway...
Ilias95
saintTUX
saintTUX
 
Δημοσιεύσεις: 1548
Εγγραφή: 29 Απρ 2011, 23:26
Εκτύπωση

Re: Τα πάντα για την C

Δημοσίευσηαπό migf1 » 21 Μαρ 2012, 21:30

Ilias95 έγραψε:Ναι, το κατάλαβα ότι είναι immutable.
Το γιατί ρωτάω. Γιατί έτσι όπως το εξηγώ μου ακούγεται σωστό. :P
Στην παραπάνω εξήγηση που δίνω, στο γιατί θεωρώ ότι κανονικά θα άλλαζε το string λέω κάτι λάθος;...

Το πρόβλημα είναι εδώ..

Μορφοποιημένος Κώδικας: Επιλογή όλων
*p = 'X';

όπου προσπαθείς να κάνεις ανάθεση σε read-only περιοχή μνήμης ;)
Go under the hood with C: Pointers, Strings, Linked Lists
Άβαταρ μέλους
migf1
powerTUX
powerTUX
 
Δημοσιεύσεις: 2082
Εγγραφή: 03 Ιουν 2011, 16:32
Εκτύπωση

Re: Τα πάντα για την C

Δημοσίευσηαπό Ilias95 » 21 Μαρ 2012, 21:33

Δηλαδή το περιεχόμενο όλων των διευθύνσεων μνήμης χαρακτηρίζεται σαν μεταβλητό ή read-only;
Και αν ναι, ο χαρακτηρισμός γίνεται απ' τη C ή απ' το ίδιο το σύστημα;
Ilias95
saintTUX
saintTUX
 
Δημοσιεύσεις: 1548
Εγγραφή: 29 Απρ 2011, 23:26
Εκτύπωση

Re: Τα πάντα για την C

Δημοσίευσηαπό migf1 » 21 Μαρ 2012, 21:41

Όχι, δεν χαρακτηρίζεται ως read-only όλη η μνήμη γενικώς. Η μνήμη που καταλαμβάνει το char *str = "String" (αυτά τα 7 συνεχόμενα bytes δηλαδή) είναι read-only. Οπότε είτε πας να τα αλλάξεις απευθείας είτε μέσω άλλου δείκτη, δεν σε αφήνει ( seg-fault ).

Αν θες να μπορείς να αλλάξεις τα περιεχόμενα της μνήμης που καταλαμβάνει το str, τότε ΔΕΝ πρέπει να το ορίσεις και να το αρχικοποιήσεις ως δείκτη χαρακτήρων (char *), αλλά ως πίνακα χαρακτήρων (char []).

ΥΓ. Μπορείς να το ορίσεις σαν δείκτη χαρακτήρων, ΧΩΡΙΣ όμως να το αρχικοποιήσεις, οπότε σε αυτή την περίπτωση ΔΕΝ θα είναι read-only, αλλά για να το χρησιμοποιήσεις ως string θα πρέπει να δεσμεύσεις χειροκίνητα τη μνήμη που θα χρειαστείς για το μέγιστο μήκος του, με malloc()/calloc() ... δυναμική διαχείριση μνήμης... αλλά νομίζω δεν έχει μιλήσει ακόμα για αυτά το βιβλίο, έτσι δεν είναι;
Go under the hood with C: Pointers, Strings, Linked Lists
Άβαταρ μέλους
migf1
powerTUX
powerTUX
 
Δημοσιεύσεις: 2082
Εγγραφή: 03 Ιουν 2011, 16:32
Εκτύπωση

Re: Τα πάντα για την C

Δημοσίευσηαπό Ilias95 » 21 Μαρ 2012, 21:49

Μάλλον δεν διατύπωσα σωστά αυτό που εννοούσα.

Η απορία μου είναι αν ισχύει γενικά ότι κάθε θέση μνήμης του υπολογιστή μπορεί να βρίσκεται σε δύο καταστάσεις. Σε read-only ή σε μεταβλητή κατάσταση.
Και αν ισχύει το παραπάνω, ο διαχωρισμός για το αν μια θέση μνήμης είναι read-only ή όχι γίνεται απ' το σύστημα ή απ' την C;
Ilias95
saintTUX
saintTUX
 
Δημοσιεύσεις: 1548
Εγγραφή: 29 Απρ 2011, 23:26
Εκτύπωση

Re: Τα πάντα για την C

Δημοσίευσηαπό migf1 » 21 Μαρ 2012, 21:56

Εξ' ορισμού οι μεταβλητές (variables) είναι read/write περιοχές μνήμης, εκτός αν τις ορίσεις εσύ να είναι write-once/read-only (αυτό συνήθως το κάνεις με το keyword const).

Στην προκειμένη περίπτωση, ο συμβολισμός...

Μορφοποιημένος Κώδικας: Επιλογή όλων
char *str = "String";

ορίζει 7 bytes μνήμης (+1 είναι ο χαρακτήρας '\0' που τον βάζει αυτόματα στο τέλος) τα οποία τα κάνεις write-once με την αρχικοποίηση, κι από εκεί και μετά είναι read-only.

Αντίθετα, ο συμβολισμός...

Μορφοποιημένος Κώδικας: Επιλογή όλων
char str[] = "String";

ορίζει 7 bytes μνήμης που είναι read/write.
Go under the hood with C: Pointers, Strings, Linked Lists
Άβαταρ μέλους
migf1
powerTUX
powerTUX
 
Δημοσιεύσεις: 2082
Εγγραφή: 03 Ιουν 2011, 16:32
Εκτύπωση

ΠροηγούμενηΕπόμενο

Επιστροφή στο Ανάπτυξη Λογισμικού / Αλγόριθμοι