Jump to content



σε C : καταχώρηση των δεδομένων του αρχείου σε δομή


Sophoclis

Recommended Posts

SirDiman έχω μπλέξει άσχημα με τα API σε αυτό το project, θα αναρτήσω τώρα το καινούργιο πρόβλημα που συμβαίνει, το οποίο είναι απόλυτα λογικό αλλά πώς να το λύσω...

Ναι εννοείτε αυτό που λές, αλλά εγώ λέω γιατί να μην διαβάζω από το αρχείο και να τα βάζω απευθείας στην structure, είναι το αρχικό πρόγραμμα που παράθεσα στην αρχή και τώρα λύθηκε και αυτό ...οπότε πιο το πλεονέκτημα να μπαίνω στην διαδικασία της χρήσης buffer?? θέμα ταχύτητας?? αφού υποθέτω είναι πιο γρήγορο παρά από το να έχεις ανοικτό το αρχείο μέχρι να διαβάσεις ενα-ενα τους χαρακτήρες...γιατί ΟΚ στο παράδειγμα μου μιλάμε για μικρό αρχείο αλλά σε ενα τεράστιο αρχείο τότε πάμε σε buffer..... Αυτή είναι η εξήγηση που δίνω!!!

τώρα το πρόβλημα είναι ότι αφού στην structure tp_book ορίζουμε

tp_book[4]; αυτό κτυπά όταν κάνω attach την shared memory γιατί αναμένεται να μου επιστρέψει pointer δηλαδή

int shmid, semid;

//char *shmem;

struct sembuf oper[1] = {0, 1, 0};

union semun arg;

if (argc < 2)

{ /* Check if server's port number is given */

write(STDERR_FILENO,"ERROR, no port provided\n",24);

exit(1);

}

//Create shm

if ((shmid = shmget(SHMKEY, sizeof(book)*howManyBooks, IPC_CREAT | PERMS)) < 0) //SHMSIZ

error("shmget");

printf("Created shared memory region with identifier %d\n", shmid);

//Create semaphore

if ((semid = semget(SEMKEY, 1, IPC_CREAT | PERMS)) < 0)

error("semget");

printf("Created semaphore with identifier %d\n", semid);

//Initialized semaphore

arg.val=0;

if (semctl(semid, 0, SETVAL, arg) < 0)

error("semctl");

write(STDIN_FILENO,"Initialized semaphore to lock shared memory region\n",52);

//Attach shm

// if ((shmem = shmat(shmid, NULL, 0)) == (char *) -1) //shmem

// error("shmat");

books = shmat(shmid, NULL, 0);

write(STDIN_FILENO,"Attached shared memory region\n",30);

Link to comment
Share on other sites

αυτό που θα ήθελα να σε ρωτήσω είναι:

1) γιατι προτίνεις να βάλουμε το αρχείο σε buffer αντίς να διαβάζουμε απευθείας από το αρχείο...?

2) Ποίος ο λόγος για define αφού είναι καθορισμένα by default :

#ifndef SEEK_END

#define SEEK_END 2

#endif

#ifndef STDOUT

#define STDOUT 1

#endif

#ifndef STDERR

#define STDERR 2

#endif

3) return(nob); //return the pointer to the buffer. MUST DELETE LATER!!! για θέμα μνήμης MUST Delete later ?

1. To buffering καλό είναι να γίνεται πάντα για πολλούς και διάφορους λόγους, ειδικά σε περιπτώσεις που τα δεδομένα μπορεί να αλλάξουν για κάποιο λόγο... Πχ κάνοντας buffering στο αρχείο σου, μπορείς να το απελευθερώσεις γρήγορα για κάποιον άλλο, μπορείς να αποφύγεις αλλαγές που μπορεί να συμβούν στο αρχείο, μπορείς να κάνεις πολλές μετατροπές σε διάφορα στάδια κτλ... Ακόμα και το λειτουργικό έναν δικό του buffer του αρχείου σου δίνει, ότι πραγματική πρόσβαση... Το ίδιο ισχύει στα πάντα στο λειτουργικό, δηλαδή τα sockets έχουν δικούς τους buffers, το video έχει δικό του buffer κτλ... Για να καταλήξουν από το φυσικό επίπεδο στο πρόγραμμά σου κάποια δεδομένα μπορεί να περάσουν από ένα σωρό buffers και από άλλους τόσους μετά να χρησιμοποιήσεις εσύ... Επίσης το buffering είναι πολύ σημαντικό στις επικοινωνίες όπου η ταχύτητα είναι μεγάλη και οι hardware buffers μικροί, γιαυτό υπάρχουν ειδικοί αλγόριθμοι για γρήγορο και ευέλικτο buffering, όπως πχ οι κυκλικοί buffers με μέγεθος της δύναμης του 2 (δηλαδή 2,4,8,16,32 κτλ). Αυτό όμως είναι άλλη ιστορία και επίσης έχει επεκτάσεις και στο multithreading, όπου το buffering σώζει ζωές...

2. Ο λόγος που τα κάνεις define είναι γιατί δεν ξέρεις σε ποιο header υπάρχουν τα definitions, οπότε αν είναι στο stdio.h το οποίο δεν πρέπει να τα χρησιμοποιήσεις, τότε πρέπει να τα κάνεις μόνος σου... Από την άλλη "απαγορεύεται" να χρησιμοποιείς σκέτους αριθμούς μέσα στον κώδικά σου, γιατί γίνεται ακαταλαβίστικος και δεν μπορεί να συντηρηθεί εύκολα, ούτε ακόμα και από σένα που τον έχεις γράψει...

3. το "must delete" αφορά τον pointer της μνήμης στον οποίο έγινε allocation ένα block μνήμης... Δηλαδή αυτό που συναίβει είναι ότι δήλωσες έναν Pointer κάπου στην μνήμη, μετά με την malloc δημιούργησες ένα block μνήμης κάπου και έσωσες την διεύθυνση του block στον πρώτο pointer. Όσο ζει αυτός ο pointer (δηλαδή είναι στο scope σου, που λένε), ξέρεις που βρίσκεται αυτό το block την μνήμης. Αν για κάποιο λόγο χαθεί ο pointer δεν ξέρεις πια που είναι το block της μνήμης... Επειδή η C δεν έχει garbage collector (και καλύτερα που δεν έχει), αυτό το block μνήμης θα μείνει για πάντα εκεί, χωρίς να μπορέσεις να το ξαναχρησιμοποιήσεις, οπότε αν αυτό συμβεί πολλές φορές, τότε κάποια στιγμή θα σου τελειώσει η μνήμη... αυτό είναι το λεγόμενο memory leak και είναι η σύγχρονη κατάρα των προγραμματιστών και των apis... Οπότε πάντα όταν δημιουργείς ένα block μνήμης με την malloc θα πρέπει να το απελευθερώνεις με την free(), επίσης τα apis τα οποία χρησιμοποιούν την malloc και δεν απελευθερώνουν την μνήμη, πρέπει να προειδοποιούν τον προγραμματιστή και φυσικά ο προγραμματιστής να ακολουθεί τις οδηγίες... Από την άλλη, υπάρχουν γλώσσες που έχουν τον λεγόμενο garbage collector, αλλά είναι τόσο bloated όσων αφορά την διαχείριση της μνήμης, που είναι τραγικό, ενώ το μόνο που χρειάζεται είναι λίγο προσοχή...

Link to comment
Share on other sites

Ρε φίλε πραγματικά είσαι όλα τα βιβλία μαζί Unix, C και βάλε...Πραγματικά Respect!!! δεν θα σε ρωτήσω πώς τα καταφέρνεις ή και άλλες ερωτήσεις που με κάνου περιέργο και μου κεινούν το ενδιαφέρον. Απλά θα ακολουθήσω την συμβουλή σου με τα 3 βιβλία που μου πρότεινες!!!

να σε ρωτήσω, μπορώ μέσα στον κώδικα μου , να καλέσω ένα άλλο εκτελέσιμο αρχείο? παρά να βάλω τον κώδικα που κάναμε σε function. Αν ναί και μπορεί να μου πείς καλώς..

επίσης στο πρόβλημα μου , που θέλω να κάνω attach την shared memory στην structure tp_book book[4] γίνεται με casting ?

Link to comment
Share on other sites

το books[4] είναι ήδη ένα block μνήμης και το (&books) είναι ο pointer που δείχνει το block αυτό... Εσύ θες έναν pointer που να δείχνει στην shared memory, η οποία είναι ένα άλλο block μνήμης... Άλλο ο pointer που δείχνει κάπου και άλλο το block της μνήμης, μην τα μπερδεύεις...

Ο pointer είναι ουσιαστικά ένα html link που το πατάς και σε πάει στην σελίδα, δεν είναι το περιεχόμενο της σελίδας... μπορείς να έχεις ένα link το οποίο είναι άδειο πχ και οποιαδήποτε στιγμή να το κάνεις να δείχνει μια σελίδα, ή να έχεις μια σελίδα και να δημιουργήσεις ένα link γι' αυτή... το book[4] είναι η html σελίδα σου...

Το casting είναι καθαρά compile time υπόθεση, δεν υπάρχει ουσιαστικά casting όταν τρέχει ο κώδικας (ή στην assembly), απλά υπάρχει για να σε προστατεύει ο compiler από λάθη... Όπου βλέπεις void*, όπως στην shmat, σημαίνει απλά ότι θα σου γυρίσει κάτι το οποίο παρ' το και κάντο ότι θες, αυτό θα έχει πάντα το ίδιο μέγεθος... εκεί θα χρειαστείς casting σε ένα pointer από array από books... Από εδώ σε αφήνω να το σκεφτείς και να το ψάξεις λίγο τι εννοώ...

Όσο για τις γνώσεις που λες, αν ασχοληθείς μπορείς να ξέρεις τα 10 πλάσια από μένα ή από οποιοδήποτε άλλο... ο προγραμματισμός είναι λογική και γυμναστική, γι' αυτό όσο το αφήνεις σε αφήνει... και γω δεν είμαι προγραμματιστής, αλλά με την ενασχόληση μαθαίνω... και μάλιστα ακόμα μαθαίνω, δεν τελειώνει ποτέ...

Link to comment
Share on other sites

Οσο πάνε ξεκαθαρίζει το τοπίο. Μου θύμισες και ποίο ξεκάθαρα τους pointer. Ακόμα 1000 ευχαριστώ! αν κατάλαβα σωστά με το "casting σε ένα pointer από array από books"

τότε το tp_book books[4] θα το αλλάξω σε tp_book *books !!

πάντως δούλεψε:T:

το θέτεις πολύ σωστά για τον προγραμματισμό, και χωρίς να πενεφτώ τουλάχιστο κατα την διάρκεια της σχολής είμου από τους καλούς , τώρα μετά απο 1,5 χρόνο αποχή από Java και 2-3 χρόνια αποχής απο C , νίωθω αρχάριος και πάλι !! ελπίζω απο εδώ και εμπρός να αφοσιωθώ!!

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Δημιουργία...

Important Information

Ο ιστότοπος theLab.gr χρησιμοποιεί cookies για να διασφαλίσει την καλύτερη εμπειρία σας κατά την περιήγηση. Μπορείτε να προσαρμόσετε τις ρυθμίσεις των cookies σας , διαφορετικά θα υποθέσουμε ότι είστε εντάξει για να συνεχίσετε.