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

Accessing struct members - C


Dr.Fuzzy

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

Δημοσ.

@imitheos

εμένα δουλεύει κανονικά το srand, αλλά (Evgenios1) όντως το θέμα με το time αλλάζει πράγματι ανά compiler οπότε to be on the portable side το άλλαξα σε NULL.

 

Τώρα στο ζουμί.

 

Έτσι σκάει:

 

>
/*
* free ants placement
*/
free_ants_place(int *ants_place)
{
   if (ants_place != 0)
   {
     free(ants_place);
     ants_place = NULL;
   }
}

 

Έτσι όχι:

 

>
     ants_place = NULL;
     free(ants_place);

 

Επίσης @Evgenios1 γιατί καλείς 4 φορές την deallocation function;

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

>free_ants_place(int *ants_place)
{
   if (ants_place != 0)
   {
     free(ants_place);
     ants_place = NULL;
   }
}  

Αυτο σκαει;

 

Αν εχεις τη καλοσυνη ανεβασε τη main. + αν το IDE σου εχει breakpoint, βαλε ενα στη γραμμη if(ants_place...

 

Αν και νομιζω οτι καλεις δυο φορες την free_ants_place, και σου δημιουργει το προβλημα. Αν προσεξεις, στη safe_free περναω των pointer by ref και οχι by val, για να τον μηδενισω.

 

Επίσης @Evgenios1 γιατί καλείς 4 φορές την deallocation function;
Τπτ, απλος να δεις μονος σου οτι δεν υπαρχει πρβλημα αν την καλεσω παραπανω φορες, με αντιθεση τη free.
Δημοσ.
>free_ants_place(int *ants_place)
{
   if (ants_place != 0)
   {
     free(ants_place);
     ants_place = NULL;
   }
}  

Αυτο σκαει;

 

περίεργο αλλά ναι.

 

Αν εχεις τη καλοσυνη ανεβασε τη main. + αν το IDE σου εχει breakpoint, βαλε ενα στη γραμμη if(ants_place...

 

Αυτή τη στιγμή είμαι με το Laptop και έχω διαθέσιμα vi + gcc μόνο (στο Desktop έχω code::blocks) οπότε breakpoint δύσκολο.

 

Η main μου

 

>
/*
*  main program
*/
int main(int argc, char *argv[])
{
   const char *filename;
   struct TSP_data problem;
   int *ants_place;

   if (argc < 2)
   {
     filename = "./TSP/ch150.tsp";
   }
   else
   {
     filename = argv[1];
   }

   //debug
   load_TSP_data(&problem, filename);
   ants_place = init_ants_place(&problem);
   //printf("ith ant placement: %d\n", *(++ants_place)); // debug
   free_ants_place(ants_place);
   
   return 0;
}

 

Όπα...μόλις τώρα είδα ότι σκάει όταν κάνω uncomment την printf...ίσως επειδή αυξάνω τη θέση του pointer *(++ants_place)..; Επίσης και αν έχω την printf με *(++ants_place) μέσα στο ίδιο το function, σκάει ξανά. Αν είναι *ants_place στην printf τότε μια χαρά! Πολύ περίεργο, μπερδεύτηκα!!!

 

Αν και νομιζω οτι καλεις δυο φορες την free_ants_place, και σου δημιουργει το προβλημα

 

Το σκέφτηκα και εγώ αλλά όχι.

 

Αν προσεξεις, στη safe_free περναω των pointer by ref και οχι by val, για να τον μηδενισω.

 

To είδα, αλλά είναι ουσιαστικά το ίδιο, αφού τελικά η free και στις δύο περιπτώσεις λαμβάνει τον pointer. Δεν νομίζω ότι παίζει ρόλο.

 

Τπτ, απλος να δεις μονος σου οτι δεν υπαρχει πρβλημα αν την καλεσω παραπανω φορες, με αντιθεση τη free.

 

A, OK. Επίσης θα μπορούσα να κάνω ένα while αντι για if, οπότε αν κάνει deallocate failure να επιμένει μέχρι να γίνει free

 

Πολυ quote ρε παιδί μου...

Δημοσ.
Όπα...μόλις τώρα είδα ότι σκάει όταν κάνω uncomment την printf...ίσως επειδή αυξάνω τη θέση του pointer..; Περίεργο.

Καθολου!!!!! στη θεση -8 (αν δε κανω λαθος, και φυσικα εξαρτατε απο τον Allocator) ειναι αρχη του heap struct που εχει τα δεδομενα του allocator

 

πχ

η malloc(20) σου επιστρεφει 50230

- - - - - - - - - virtaul memory - - - - - - - - - -

|5022|heap struct |50230| my data...

 

Αν πας τον δεικτι στο my data η free δεν θα μπορει να βρει τον heap struct για να κανει το deallocate!

Δημοσ.

Λογικό μου ακούγεται αν και δεν έχω debugger για να το τσεκάρω τώρα.

 

Ωραία, οπότε μη μου πεις ότι πρέπει να κάνω αυτό (δηλαδή να γυρνάω τον pointer στο array στην θέση 0 κάθε φορά πριν το deallocation!!!) :-D

 

>
   printf("ith ant placement: %d\n", *(++ants_place)); // εμπρός
   *(--ants_place); // όπισθεν

 

δεν είναι και πολύ πρακτικό!

Δημοσ.
Λογικό μου ακούγεται αν και δεν έχω debugger για να το τσεκάρω τώρα.

 

Ωραία, οπότε μη μου πεις ότι πρέπει να κάνω αυτό (δηλαδή να γυρνάω τον pointer στο array στην θέση 0 κάθε φορά πριν το deallocation!!!) :-D

 

>
   printf("ith ant placement: %d\n", *(++ants_place)); // εμπρός
   *(--ants_place); // όπισθεν

 

δεν είναι και πολύ πρακτικό!

 

Το *(--ants_place); δεν θα έπρεπε να είναι --ants_place; ?

Επίσης, κάτι τέτοιο δεν σου κάνει ?

>
   printf("ith ant placement: %d\n", *(ants_place + 1)); 

Δημοσ.
Το *(--ants_place); δεν θα έπρεπε να είναι --ants_place; ?

 

Όχι. θέλω να πάω στην προηγούμενη θέση του array (μειώνω το address όχι το value).

Επίσης, κάτι τέτοιο δεν σου κάνει ?

>
   printf("ith ant placement: %d\n", *(ants_place + 1)); 

 

είναι το ίδιο με *(ants_place++)...

Δημοσ.
Όχι. θέλω να πάω στην προηγούμενη θέση του array (μειώνω το address όχι το value).

Ναι και εγώ για την διεύθυνση μιλάω όχι για την τιμή.

Το --ants_place μειώνει κατά ένα τον δείκτη. Έπειτα το *() που έχεις τον κάνει

dereference και παίρνει την τιμή του χωρίς όμως να την κάνει τίποτα.

 

είναι το ίδιο με *(ants_place++)...

 

Δεν είναι το ίδιο γιατί δεν αλλάζει τον δείκτη.

>
printf("ith ant placement: %d\n", *(++ants_place)); // εμπρός
   *(--ants_place); // όπισθεν  

 

Εδώ του λες να αυξήσει κατά ένα τον δείκτη και να τυπώσει την τιμή του

(δηλαδή αν μιλάμε για array την 2η τιμή του) και έπειτα μειώνεις και πάλι

τον δείκτη ώστε να παίζει το free. Με το *(ants_place + 1) τυπώνεις την 2η

τιμή που θέλεις αλλά ο δείκτης μένει ίδιος οπότε το free θα παίζει.

Δημοσ.
Ναι και εγώ για την διεύθυνση μιλάω όχι για την τιμή.

Το --ants_place μειώνει κατά ένα τον δείκτη. Έπειτα το *() που έχεις τον κάνει

dereference και παίρνει την τιμή του χωρίς όμως να την κάνει τίποτα.

 

ναι αυξάνω την θέση του pointer ++ και κάνω dereference * για να τυπώσω την τιμή του object.

 

Δεν είναι το ίδιο γιατί δεν αλλάζει τον δείκτη.

>
printf("ith ant placement: %d\n", *(++ants_place)); // εμπρός
   *(--ants_place); // όπισθεν  

...αλλά ο δείκτης μένει ίδιος...

 

Έχεις δίκιο! Δυστυχώς επειδή έχω κάποια χρόνια να γράψω C, γράφω τελείως εμπειρικά (θεωρεία θέλω φρεσκάρισμα)!

Δημοσ.
ναι αυξάνω την θέση του pointer ++ και κάνω dereference * για να τυπώσω την τιμή του object.

>
   *(--ants_place); // όπισθεν  

Δεν εννοούσα το printf. Αυτό που μειώνεις τον δείκτη για το free εννοούσα.

Εδώ το dereference δεν έχει κάποιο νόημα γιατί δεν κάνεις κάτι την τιμή, για αυτό

ρώτησα πριν γιατί δεν το έκανες σκέτο "--ants_place;"

 

Έχεις δίκιο! Δυστυχώς επειδή έχω κάποια χρόνια να γράψω C, γράφω τελείως εμπειρικά (θεωρεία θέλω φρεσκάρισμα)!

 

Το ανέφερα για να βοηθήσω ότι γίνεται και απευθείας χωρίς να αυξάνεις και να

μειώνεις τον δείκτη. Δεν το έκανα για να στην πω. Συγγνώμη αν σου έδωσα τέτοια εντύπωση.

Δημοσ.
>
   *(--ants_place); // όπισθεν  

 

Δεν εννοούσα το printf. Αυτό που μειώνεις τον δείκτη για το free εννοούσα.

Εδώ το dereference δεν έχει κάποιο νόημα γιατί δεν κάνεις κάτι την τιμή, για αυτό

ρώτησα πριν γιατί δεν το έκανες σκέτο "--ants_place;"

 

ΟΚ, αναφερόμουν στην printf. Εδώ ούτε που το πρόσεξα (copy-paste γαρ!), όντως δεν χρειάζεται το *.

 

Το ανέφερα για να βοηθήσω ότι γίνεται και απευθείας χωρίς να αυξάνεις και να

μειώνεις τον δείκτη. Δεν το έκανα για να στην πω. Συγγνώμη αν σου έδωσα τέτοια εντύπωση.

 

Όχι ρε προς θεού!!! Καμία σχέση, δεν το πείρα έτσι, το ακριβώς αντίθετο! Άλλωστε το δήλωσα εξαρχής ότι έχω σκουριάσει στη C. Τhanx που βοηθάς.:-)

Δημοσ.

Μέχρι να ξεσκουριασεις, βοηθάει πολύ να ενεργοποιήσεις όλα τα warning

στον compiler σου (στον gcc βάζεις -Wall). π.χ

>
*(--ants_place);
fprintf(stderr,"\nAbort!\n\n",buffer);

 

δίνει

>
warning: value computed is not used
warning: too many arguments for format

 

Έτσι βλέπεις αμέσως αυτό που λέγαμε πριν ότι δεν χρειάζεται το *()

και επίσης πράγματα που ξεφεύγουν καμμιά φορά στο μάτι όπως ότι δεν έχει

δηλωθεί format για το buffer.

Δημοσ.

Το ανοίγω πάλι για να ρωτήσω κάτι ακόμα με structs επειδή χρειάστηκε να αλλάξω κάποια πράγματα στον αρχικό κώδικα. Λοιπόν έχω το παρακάτω struct,

 

>struct single_ant
{
 int tour_length; /* the ant's tour length */
 int* tour; /* ant's memory storing (partial) tours */
 int* visited; /* visited cities */
};

 

που κάνει point στα ants.

 

>struct single_ant *ants; /* structure of type single_ant */

 

καλώ μέσα στη main ένα function που δημιουργεί τυχαίες τιμές και τις επιστρέφει by reference στο κάθε ant[n].

 

>void ants_place(struct TSP_data *problem, struct single_ant *ants)
{
 int i;
 int r;
 srand(time(NULL)); /* randomness depends on time */

 ants = (int *) malloc( problem->n * sizeof(int)); /* allocate placement memory (n int elements) dynamically */
 
 // debug
 if (ants != 0)
 {
   printf("Allocation of %ld bytes for the initial ants placement was successful\n\n", problem->n * sizeof (int));
 }
 else
 {
   fprintf(stderr, "\nERROR: Attempt to allocate %ld bytes for the initial ants placement failed !\n", problem->n * sizeof (int));
   exit(1);
 }
 
 /* place ants randomly */
 for (i = 0; i < problem->n; i++)
 {
   r = rand() % (problem->n - 1) + 1;
   /* since path is from nest to food use nodes-1 to place ants to all nodes 
      except the target (food) node */
   ants[i].tour[0] = r;
   ants[i].visited[r] = 1;
}

 

και τελικά στην main την καλώ ως εξής:

 

>ants_place(&problem, ants);
 
//for (i=0; i<problem.n; i++)
//{
//  printf("ith ant placement: %d\n", ants[i]); // debug
//}

 

και τρώω seg.fault...

 

Τα φώτα σας please. :-)

Αρχειοθετημένο

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

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