Προς το περιεχόμενο

C Προβλημα με δυναμικη διχειριση μνημης.


antonis1245

Προτεινόμενες αναρτήσεις

  • Απαντ. 142
  • Δημ.
  • Τελ. απάντηση

Συχνή συμμετοχή στο θέμα

Link.png Site: Εδώ

Μιλάμε για το "επίμαχο" πρόγραμμα. Αυτό που είδε ο Defacer ότι έχω κάνει UB (όχι για το παράδειγμα με το πίνακα που έβαλε ο DDevil)

 

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Σίγουρα;

Αφού επιτρέπεται να βάζω διαφορά!


Στο σύνδεσμο που έδωσεςLink.png Site: How to C (as of 2016)

Instead of:

long diff = (long)ptrOld - (long)ptrNew;

Use:

ptrdiff_t diff = (uintptr_t)ptrOld - (uintptr_t)ptrNew;

 

εγώ δεν έβαλα καθόλου cast

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Όχι, δεν επιτρέπεται να βάζεις διαφορά γενικά και αόριστα (μάλιστα το έχω αναφέρει ο ίδιος σε προηγούμενο post εδώ το οποίο όπως φαίνεται δε θεώρησες αρκετά ουσιώδες για να το λάβεις υπόψη στον έξυπνο προγραμματισμό, όπως είχες κάνει και την προηγούμενη φορά που είπα ότι η αφαίρεση είναι το UB).

 

Το temp μπορεί να έχει γίνει allocated σε νέο σημείο μνήμης, στην οποία περίπτωση το name έχει γίνει freed άρα δεν κάνει point σε τίποτα άρα οτιδήποτε κι αν κάνεις μαζί του είναι UB.

 

Ακόμα κι αν δεν είχε γίνει το free παρα μόνο το reallocation πάλι θα ήταν UB επειδή αφαιρείς δύο άσχετους μεταξύ τους pointers.

 

Ελπίζω να βρήκες την ουσία αρκετά ουσιώδη για τα γούστα σου γιατί δε σκοπεύω να χάσω άλλο χρόνο.

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Όχι ..έχει γίνει free, αλλά δεν έχει διαγραφεί η τιμή του, η διεύθυνση. Αυτό είναι το θέμα με τη C. Κάνει επακριβώς ότι θες. Δεν αφαιρώ άσχετους δείκτες. Το έχω δοκιμάσει προσθέτοντας επίτηδες πολλαπλάσια των 50000 bytes σε κάθε νέα εγγραφή, και άλλαζε το name χωρίς κανένα πρόβλημα. Το name παίρνει την τιμή του temp μετά τους υπολογισμούς. Άρα ουδέποτε χρησιμοποιώ το name ενώ έχει γίνει invalid (μου αρέσει αυτός ο όρος).

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

Διάβασα αυτό που έδωσες ως μη επιτρέπόμενο. Αυτό που δεν κατανόησες, είναι ότι αντί να κρατάω τη διαφορά, offset, του top με το name, έχω και τους δύο δείκτες, και απλά κάνω το relocation. Θα μπορούσε κανείς να κρατάει το offset, αφού αθροίζει κάπου το μήκος του κάθε εισαγόμενου αλφαριθμητικού, και έτσι σε κάθε νέα εγγραφή να φτιάχνει ένα νέο δείκτη name + offset.

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

@Off

He he :) έβαλα στοίχημα με τον εαυτό μου πριν μπω εδώ ότι θα σας δω να "τρωγόσαστε" μεταξύ σας για το ποιος τα λέει καλύτερα. Το κέρδισα! :D  :X

 

Εγώ λέω να αφήσετε το "βέλτιστο" γιατί στο τέλος με τόσο "SPAM" ο @TS θα έχει ένα κεφάλι καζάνι που δεν θα μάθει-ξέρει ούτε το βασικό. Πόσο μάλλον το "βέλτιστο" (που ο καθένας το βαφτίζει όπως θέλει).

 

Be more practice guys!!!

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Καλημέρα,

 

Δεν θέλω να σε προπηλακίσω φίλε Μ2000 αλλά παρά την φιλότιμη προσπάθεια που έχεις καταβάλει, ο κώδικας σου (τον μελέτησα λίγο και μπορώ να πω πως ζαλίστηκα σε μία φάση) υστερεί αρχικά σε μία βασική προγραμματιστική αρχή που πιστεύω ακόμα και ο σκληροπυρηνικός Defacer δεν θα μπορεί να διαφωνήσει:

KISS - Keep It Simple *Sorry

 

Οι δομές στη C, είναι για αυτό το σκοπό και διερωτόμαι εφόσον έμαθες να χρησιμοποιείς αγόγγυστα την realloc, γιατί τότε πολύ απλά δεν φτιάχνεις μία δομή σαν και αυτή που σου έδειξε ο ημίθεος και να έχεις ένα δείκτη σε ένα πίνακα από δομές που θα τον κάνεις realloc σε κάθε εισαγωγή; Κάτι τέτοιο δηλαδή:

#define TERM_SIZE 255+1
typedef struct _DictTerm{
    char gr[TERM_SIZE];
    char en[TERM_SIZE]; 
}DictTerm;

typedef struct _Dict{
    int DictSz;
    DictTerm term;
}Dict;
 
void* growUp(Dict **dict){
   return realloc(*dict, ++(*dict)->DictSz * sizeof(Dict));
}
 
Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Όχι ..έχει γίνει free, αλλά δεν έχει διαγραφεί η τιμή του, η διεύθυνση. Αυτό είναι το θέμα με τη C. Κάνει επακριβώς ότι θες. Δεν αφαιρώ άσχετους δείκτες. Το έχω δοκιμάσει προσθέτοντας επίτηδες πολλαπλάσια των 50000 bytes σε κάθε νέα εγγραφή, και άλλαζε το name χωρίς κανένα πρόβλημα. Το name παίρνει την τιμή του temp μετά τους υπολογισμούς. Άρα ουδέποτε χρησιμοποιώ το name ενώ έχει γίνει invalid (μου αρέσει αυτός ο όρος).

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

Διάβασα αυτό που έδωσες ως μη επιτρέπόμενο. Αυτό που δεν κατανόησες, είναι ότι αντί να κρατάω τη διαφορά, offset, του top με το name, έχω και τους δύο δείκτες, και απλά κάνω το relocation. Θα μπορούσε κανείς να κρατάει το offset, αφού αθροίζει κάπου το μήκος του κάθε εισαγόμενου αλφαριθμητικού, και έτσι σε κάθε νέα εγγραφή να φτιάχνει ένα νέο δείκτη name + offset.

 

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

  • Like 1
Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Ωπ, πολλά μηνύματα.

 

λολ, μόνο στο ινσόμνια καταλήγει ένα θέμα για κώδικα στο ποιος είναι ο πιο παλιός, ο πιο ANSI C compatible και ο op μένει με το bug στο χέρι.

 

Φίλε πόσταρε το σε κανένα stackoverflow να δεις φως, διαφορετικά ακόμα και για ένα hello word θα πάρεις για απάντηση ενα paper εξειδικευμένης μπουρδολογίας.

Έχεις δίκιο ότι πολλές φορές ξεφεύγουμε και ένα νήμα καταλήγει να έχει τεχνικές λεπτομέρειες για compilers και πρότυπα και δεν ξέρω τι. Κανείς δεν διαφωνεί σε αυτό. Συνήθως όμως γίνεται αφού έχουν απαντηθεί τα ερωτήματα του OP οπότε δεν βρίσκω κακό σε αυτό. Μην ξεχνάμε ότι εκτός από τον OP, μπορεί μελλοντικά το νήμα να διαβαστεί και από άλλους που να τους φανεί χρήσιμη η τεχνική λεπτομέρεια.

 

ενώ θα μπορούσατε και εσείς με πμ να τους ενημερώσετε για την ασχετοσύνη τους.

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

 

Φυσικά δεν μπορώ να μιλήσω για όλο το φόρουμ, αλλά τουλάχιστον στην περίπτωση των γνωστών-αγνώστων που "κυκλοφορούμε" στο παρόν φόρουμ, δεν θα μπορούσε να είναι πιο μακρυά από την αλήθεια. Δεν ξυπνήσαμε μια μέρα και είπαμε θα την πούμε στον M2000 για να το παίξουμε έξυπνοι.

 

post-84828-0-05238000-1452419280_thumb.jpg

 

Δες την παραπάνω εικόνα. Αυτά είναι μόλις κάποια παραδείγματα γιατί βαρέθηκα να κάνω περισσότερα. Μπες στη κεντρική σελίδα του φόρουμ του προγραμματισμού και δες π.χ τις πρώτες τρεις σελίδες. Θα δεις δεκάδες νήματα να έχουν ως τελευταία απάντηση αυτόν. Ο τύπος μπαίνει σε όλα τα νήματα και απαντάει μπούρδες χωρίς να ξέρει το αντικείμενο με αποτέλεσμα να κάνει κακό στους OP.

 

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

 

Είναι πολύ πιθανό να είμαι λάθος αλλά προσωπικά εμπίπτω στο γνωστό xkcd "someone is wrong on the internet". Μπορώ φυσικά να μην απαντήσω σε κάτι που θα δω αλλά θεωρώ ότι εφόσον συμμετέχω στο φόρουμ, έχω χρέος να σχολιάσω κάτι που γράφεται και είναι λάθος ώστε να προστατεύσω τον OP και γενικά τον αναγνώστη του νήματος. Αυτό δυστυχώς πολλές φορές καταλήγει στο να πέσω στην παγίδα ορισμένων troll όπως ο m2000 και να εκτροχιάσω κάποιο νήμα. Από αυτή την άποψη γράφουμε όσα γράφουμε και όχι για να το παίξουμε ξερόλες.

 

Επίσης ο defacer έχει απόλυτο δίκιο σε αυτό που σου είπε. Σε ένα νήμα για python, η απάντηση θα ήταν μία γραμμή και θα τελείωσε εκεί το νήμα. Η C είναι από τις λίγες γλώσσες οι οποίες σηκώνουν αυτή τη συζήτηση που σου φαίνεται ξερολίστικη και ίσως μάλιστα σε αναγκάζουν να την κάνεις γιατί αλλιώς δεν μπορείς να εξηγήσεις γιατί χρειάζεται διπλός δείκτης.

 

@gon1332.

Του imitheos η λύση είναι "σχολικού τύπου".

Lomar, θέλεις και άλλη απόδειξη trolling ? Ο κώδικάς μου που χρησιμοποιεί διακριτές δομές και (θέλω να πιστεύω πως) είναι ευανάγνωστος για ένα αρχάριο, είναι "σχολικός" ενώ ο δικός του είναι επαγγελματικός.

 

Πόση ώρα πιστεύεις θα μου πάρει να βρω ένα switch στον gcc με το οποίο να πετάει λάθος αποτέλεσμα λόγω UB ? Και μιλάω σε x86 όχι sparc ή κάποια "παράξενη" αρχιτεκτονική.

  • Like 5
Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Δημοσ. (επεξεργασμένο)

Δεν θέλω σε καμία περίπτωση να θεωρηθώ troll! Το θέμα του OP ήταν και παραμένει η διαχείριση μνήμης. Το να υπάρχουν διάφορες εκδοχές είναι καλό. Ακόμα και η αρνητική εκδοχή, η εξτρέμ. Γιατί αν δεν δει κανείς τις διαφορές δεν θα μάθει.

Δεν απορρίπτω τις διακριτές μορφές αλλά δείτε ότι στη UB δομή μου (θα τη βαφτίσω έτσι) δεν χρησιμοποιώ χαμένη μνήμη, όλα τα αλφαριθμητικά γράφονται σε ένα μεγάλο. (δεν κάνω strcat γιατί θέλω τα \0 στο τέλος). Είναι μια πρόταση! Ένα πρόγραμμα καλό είναι να "Διαβάζεται" ωραία αλλά δεν είναι απαραίτητο!

Συμμετέχω στο φόρουμ λίγο καιρό, και μπαίνω σε θέματα που με ενδιαφέρουν, προγραμματισμός και φωτογραφία. Δεν θα με δείτε αλλού! (Καθημερινά φτιάχνω και προγράμματα για τη Μ2000 που γράφω στο αντίστοιχο blog)

Δεν μπορώ να αναιρέσω την ιδέα για μένα. Ο καθένας έχει τον τρόπο του να βελτιώνεται. Απλά να μην βιάζεται να βγάζει ιδέες!

 

 

Προσθήκη:

Δεν παίζεται η C....εδώ βάζει σε πίνακα διευθύνσεις σε κώδικα...για να χρησιμοποιηθεί σε jump table...Σιγά μη γίνεται σε Python...Αλλά γιατί κάνει τέτοιες ταρζανιές η C; Είναι θέμα ταχύτητας...

https://gcc.gnu.org/onlinedocs/gcc/Labels-as-Values.html#Labels-as-Values

Επεξ/σία από M2000
Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Μα φίλε Μ2000, ένας αρχάριος δεν πιστεύεις ότι θα σπεύσει να μελετήσει έναν σωστό και ευανάγνωστο κώδικα αντί για εναν (σωστό ) μακαρονοειδες (με UB).

 

Σαφέστατα και ειναι σημαντικό το να γράφεις ευανάγνωστο κώδικα ειδικά όταν πρόκειται να διαβαστεί απο τρίτους ( και πόσο μάλλον απο έναν αρχάριο). Αν είχα άδικο τότε όλοι τα source codes της c++ online, θα έμοιαζαν με εκείνα της STL. Φυσικά εμάς δεν μας ενδιαφέρει πως έχει γίνει coded το std::unordered_map παρά μόνο το πόσο εύχρηστο, λογικό και πρακτικό ειναι το interface του.

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Δυστυχώς πολύπλοκος κώδικας παραμένει πολύπλοκος...όπως και να έχει το πράγμα...αν θέλουμε efficiency... Να γιατί τον διαχώρισα από το σχολικό κώδικα. Ο imitheos έδωσε μια σωστή λύση. Τον τσίγλισα μήπως δώσει κάτι παραπάνω...και μου την είπε. Μετά έδωσα μια ιδέα...και μετά σκέφτηκα να την υλοποιήσω εκμεταλλευόμενος την low level προσέγγιση της C. Ο κώδικας είναι εντάξει, έκανα δοκιμή stretch. Άρα τώρα ο OP που διάλεξε C έχει την λύση με struct και με all in one string.

Αυτή η δομή,των διαδοχικά πσραθετημένων αλφαριθμητικών βολεύει όταν ξέρουμε ότι δεν θα σβήσουμε στοιχείο.

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Επισκέπτης
Αυτό το θέμα είναι πλέον κλειστό για περαιτέρω απαντήσεις.

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