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

Accessing struct members - C


Dr.Fuzzy

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

Δημοσ.
Όντως, δεν χρειάζεται να κάνεις και τα δύο. Αν πριν την κλήση της load_TSP_data έχεις δεσμεύσει με malloc μνήμη για τον problem pointer, τότε αρκεί να κάνεις μόνο το πρώτο. Αν όχι και θέλεις (και πρέπει, αφού η πρώτη εντολή μέσα στη συνάρτηση είναι προσπέλαση του problem->n member) η malloc να γίνεται μέσα στην load_TSP_data στην αρχή-αρχή της, αρκεί να κάνεις μόνο το δεύτερο.

 

Αλλά το ενδιαφέρον είναι ότι αυτό που κάνεις return στο τέλος της load_TSP_data (το problem->node δηλαδή) δεν είναι pointer σε struct TSP_data, αλλά pointer σε struct point. Άρα το return type της load_TSP_data δε μπορεί να είναι struct TSP_data*, ούτε μπορείς να κάνεις assign αυτό που επιστρέφει σε έναν pointer σε struct TSP_data. :rolleyes:

 

Τώρα μπερδεύτηκα κι εγώ! :P

 

Εγώ να δεις...

 

I've created a monster:shock::shifty:

 

μέσα στη load_TSP_data έχω βάλει,

 

>
   if ((problem->node = malloc(sizeof(struct point) * problem->n)) == NULL)
       exit(EXIT_FAILURE);
   else
   {
       for (i = 0 ; i < problem->n ; i++)
       {
           fscanf(TSP_file,"%ld %lf %lf", &j, &problem->node[i].x, &problem->node[i].y );
       }
   }

 

Επίσης, στην κλήση της load_TSP_data, γιατί ως 2ο όρισμα *filename και όχι σκέτο filename;

...γιατί έγραφα από τη ξαπλώστρα στη παραλία με το iPhone! filename.

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

Μου πετάει segmentation fault :devil::devil: Ρίξτε καμιά ιδέα...

 

>
#define LINE_BUFFER_LENGTH  50

long int **distance; /* distance[i][j] matrix, from city[i] to city[j]*/

/*
*  load TSP data
*/
struct point
{
   double x;
   double y;
};

struct TSP_data
{
   char name[LINE_BUFFER_LENGTH];
   char edge_weight_type[LINE_BUFFER_LENGTH];
   long int n;
   struct point *node;
};

struct TSP_data* load_TSP_data(struct TSP_data *problem, const char *TSP_filename)
{
   problem->n=1;
   FILE *TSP_file;
   char buffer[LINE_BUFFER_LENGTH];
   long int i;
   long int j;

   if (TSP_filename != NULL)
   {
       TSP_file = fopen(TSP_filename, "r");
       assert(TSP_file != NULL);
       printf("\nReading TSP file %s ... \n\n", TSP_filename);
   }
   else
   {
       fprintf(stderr, "No TSP file found, abort\n");
       exit(1);
   }
...
... 
   return problem->node;
}


/*
*  main program
*/
int main(int argc, char *argv[])
{
   const char *filename = "att48.tsp";

   struct TSP_data problem;

   load_TSP_data(&problem, filename);

   return 0;
}

 

Αν το βάλω READ-WRITE (TSP_file = fopen(TSP_filename, "rw");) δουλεύει κανονικά...

Δημοσ.

Μου πετάει segmentation fault :devil::devil: Ρίξτε καμιά ιδέα...

 

>
#define LINE_BUFFER_LENGTH  50

long int **distance; /* distance[i][j] matrix, from city[i] to city[j]*/

/*
*  load TSP data
*/
struct point
{
   double x;
   double y;
};

struct TSP_data
{
   char name[LINE_BUFFER_LENGTH];
   char edge_weight_type[LINE_BUFFER_LENGTH];
   long int n;
   struct point *node;
};

struct TSP_data* load_TSP_data(struct TSP_data *problem, const char *TSP_filename)
{
   problem->n=1;
   FILE *TSP_file;
   char buffer[LINE_BUFFER_LENGTH];
   long int i;
   long int j;

   if (TSP_filename != NULL)
   {
       TSP_file = fopen(TSP_filename, "r");
       assert(TSP_file != NULL);
       printf("\nReading TSP file %s ... \n\n", TSP_filename);
   }
   else
   {
       fprintf(stderr, "No TSP file found, abort\n");
       exit(1);
   }
...
... 
   return problem->node;
}


/*
*  main program
*/
int main(int argc, char *argv[])
{
   const char *filename = "att48.tsp";

   struct TSP_data problem;

   load_TSP_data(&problem, filename);

   return 0;
}

 

Αν το βάλω READ-WRITE (TSP_file = fopen(TSP_filename, "rw");) δουλεύει κανονικά...

Δημοσ.

Στο fopen με κόβει ακόμα και αν τα βάλω όλα σχόλια, αφήσω μόνο αυτό και κάνω το function void! Αν το μεταφέρω μέσα στη main δουλεύει σε read mode.

Δημοσ.

Στο fopen με κόβει ακόμα και αν τα βάλω όλα σχόλια, αφήσω μόνο αυτό και κάνω το function void! Αν το μεταφέρω μέσα στη main δουλεύει σε read mode.

Δημοσ.

Εμ, το γράφεις και C.

Το δοκίμασα από περιέργρεια σε C++.

Εκεί αν το return problem->node; το κάνεις return (TSP_data*) (problem->node);

και το exit(1); το κάνεις return NULL;

κάνει compile δίχως λάθη. Η C έχει πολλές ιδιοτροπίες και είναι πολύ low level.

Αν μπορούσες να κάνεις κανένα ματζούνι και να χρησιμοποιήσεις C++ θα ήταν πολύ πιο απλά τα πράγματα.

Αλλά η CUDA δυστυχώς δεν δουλεύει σε C++ απ' ότι ξέρω...

Δημοσ.

Εμ, το γράφεις και C.

Το δοκίμασα από περιέργρεια σε C++.

Εκεί αν το return problem->node; το κάνεις return (TSP_data*) (problem->node);

και το exit(1); το κάνεις return NULL;

κάνει compile δίχως λάθη. Η C έχει πολλές ιδιοτροπίες και είναι πολύ low level.

Αν μπορούσες να κάνεις κανένα ματζούνι και να χρησιμοποιήσεις C++ θα ήταν πολύ πιο απλά τα πράγματα.

Αλλά η CUDA δυστυχώς δεν δουλεύει σε C++ απ' ότι ξέρω...

Δημοσ.
Εμ, το γράφεις και C.

Το δοκίμασα από περιέργρεια σε C++.

Εκεί αν το return problem->node; το κάνεις return (TSP_data*) (problem->node);

και το exit(1); το κάνεις return NULL;

κάνει compile δίχως λάθη. Η C έχει πολλές ιδιοτροπίες και είναι πολύ low level.

Αν μπορούσες να κάνεις κανένα ματζούνι και να χρησιμοποιήσεις C++ θα ήταν πολύ πιο απλά τα πράγματα.

Αλλά η CUDA δυστυχώς δεν δουλεύει σε C++ απ' ότι ξέρω...

 

Όχι, compile κάνει και σε μένα κανονικά αλλά στο run μου πετάει segmentation fault όπως ανάφερα παραπάνω.

 

Εμ, το ξέρω λες να είμαι μαζόχας και να θέλω να το κάνω σε C, αλλά δυστυχως C++ τσου (για την ακρίβεια δεν υποστηρίζεται επισημα)!

Δημοσ.
Εμ, το γράφεις και C.

Το δοκίμασα από περιέργρεια σε C++.

Εκεί αν το return problem->node; το κάνεις return (TSP_data*) (problem->node);

και το exit(1); το κάνεις return NULL;

κάνει compile δίχως λάθη. Η C έχει πολλές ιδιοτροπίες και είναι πολύ low level.

Αν μπορούσες να κάνεις κανένα ματζούνι και να χρησιμοποιήσεις C++ θα ήταν πολύ πιο απλά τα πράγματα.

Αλλά η CUDA δυστυχώς δεν δουλεύει σε C++ απ' ότι ξέρω...

 

Όχι, compile κάνει και σε μένα κανονικά αλλά στο run μου πετάει segmentation fault όπως ανάφερα παραπάνω.

 

Εμ, το ξέρω λες να είμαι μαζόχας και να θέλω να το κάνω σε C, αλλά δυστυχως C++ τσου (για την ακρίβεια δεν υποστηρίζεται επισημα)!

Δημοσ.
Όχι, compile κάνει και σε μένα κανονικά αλλά στο run μου πετάει segmentation fault όπως ανάφερα παραπάνω.

 

Εμ, το ξέρω λες να είμαι μαζόχας και να θέλω να το κάνω σε C, αλλά δυστυχως C++ τσου (για την ακρίβεια δεν υποστηρίζεται επισημα)!

 

Μπορείς να κάνεις paste σε spoilers όλο τον κώδικα και το att48.tsp ?

 

Πήρα τον κώδικα του μηνύματος #17 και αφού πρόσθεσα includes, αφαίρεσα τις

... και άλλαξα το return σε struct point* μου κάνει compile και τρέχει κανονικά

αλλά χωρίς ολόκληρο τον κώδικα ίσως να παίχθηκε κάτι.

Δημοσ.
Όχι, compile κάνει και σε μένα κανονικά αλλά στο run μου πετάει segmentation fault όπως ανάφερα παραπάνω.

 

Εμ, το ξέρω λες να είμαι μαζόχας και να θέλω να το κάνω σε C, αλλά δυστυχως C++ τσου (για την ακρίβεια δεν υποστηρίζεται επισημα)!

 

Μπορείς να κάνεις paste σε spoilers όλο τον κώδικα και το att48.tsp ?

 

Πήρα τον κώδικα του μηνύματος #17 και αφού πρόσθεσα includes, αφαίρεσα τις

... και άλλαξα το return σε struct point* μου κάνει compile και τρέχει κανονικά

αλλά χωρίς ολόκληρο τον κώδικα ίσως να παίχθηκε κάτι.

Δημοσ.
Μπορείς να κάνεις paste σε spoilers όλο τον κώδικα και το att48.tsp ?

 

Πήρα τον κώδικα του μηνύματος #17 και αφού πρόσθεσα includes, αφαίρεσα τις

... και άλλαξα το return σε struct point* μου κάνει compile και τρέχει κανονικά

αλλά χωρίς ολόκληρο τον κώδικα ίσως να παίχθηκε κάτι.

 

Το return θέλω να γυρνάει τα members του TSP_data, μελλοντικά θα χρειαστούν και τα υπόλοιπα (ΝΑΜΕ, COMMENT, etc) fields που διαβάζει από το *.tsp αρχειο.

Το συγκεκριμένο πρόβλημα με το seg.fault το διόρθωσα αλλά τώρα έχω άλλο seg.fault!!!

 

Λοιπόν κάνω paste όλο τον κώδικα μπας και το βρει κανένας...

 

>
/* Ant Colony Optimization (ACO)
*
*   Author: Dr. Fuzzy
*   August, 2010
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <math.h>

#define LINE_BUFFER_LENGTH  50

long int **distance; /* distance[i][j] matrix, from city[i] to city[j]*/

/*
*  load TSP data
*/
struct point
{
   double x;
   double y;
};

struct TSP_data
{
   char name[LINE_BUFFER_LENGTH];
   char edge_weight_type[LINE_BUFFER_LENGTH];
   long int n;
   struct point *node;
};

struct TSP_data* load_TSP_data(struct TSP_data *problem, const char *TSP_filename)
{
   problem->n=1;
   FILE *TSP_file;
   char buffer[LINE_BUFFER_LENGTH];
   long int i, j;

   if (TSP_filename == NULL)
   {
       fprintf(stderr, "No TSP file found, abort\n");
       exit(1);
   }
   else
   {
       TSP_file = fopen(TSP_filename, "rw");
       assert(TSP_file != NULL);
       printf("\nReading TSP file %s ... \n\n", TSP_filename);
   }

   fscanf(TSP_file, "%s", buffer);
   while (strcmp("NODE_COORD_SECTION", buffer) != 0)
   {
       if (strcmp("NAME:", buffer) == 0)
       {
           fscanf(TSP_file, "%s", buffer);
           strcpy(problem->name, buffer);
           printf("NAME: %s \n", problem->name);
           buffer[0]=0;
       }
       else if (strcmp("COMMENT:", buffer) == 0)
       {
           fgets(buffer, LINE_BUFFER_LENGTH, TSP_file);
           printf("COMMENT: %s", buffer);
           buffer[0]=0;
       }
       else if (strcmp("TYPE:", buffer) == 0 )
       {
           fscanf(TSP_file, "%s", buffer);
           printf("TYPE: %s\n", buffer);
           if (strcmp("TSP", buffer) != 0)
           {
               fprintf(stderr,"\nTSP file is differs from the standard TSPLIB format !!\n");
               exit(1);
           }
           buffer[0]=0;
       }
       else if (strcmp("DIMENSION:", buffer) == 0)
       {
           fscanf(TSP_file, "%ld", &problem->n);
           printf("DIMENSION: %ld\n", problem->n);
           assert (problem->n > 2 && problem->n < 6000);
           buffer[0]=0;
       }
       else if (strcmp("DISPLAY_DATA_TYPE", buffer) == 0)
       {
           fgets(buffer, LINE_BUFFER_LENGTH, TSP_file);
           printf("%s", buffer);
           buffer[0]=0;
       }
       else if (strcmp("EDGE_WEIGHT_TYPE:", buffer) == 0)
       {
           buffer[0]=0;
           fscanf(TSP_file, "%s", buffer);
           printf("EDGE WEIGHT TYPE: %s\n", buffer);
           if (strcmp("EUC_2D", buffer) == 0 )
           {
               //distance = euc_distance;
           }
           else
           {
               fprintf(stderr,"This EDGE WEIGHT TYPE (%s) is not yet implemented in this version !\n",buffer);
               fprintf(stderr,"\nAbort!\n\n",buffer);
               exit(1);
           }
           strcpy(problem->edge_weight_type, buffer);
           buffer[0]=0;
       }
       buffer[0]=0;
       fscanf(TSP_file,"%s", buffer);
   }

   if (strcmp("NODE_COORD_SECTION", buffer) == 0)
   {
       printf("\nFound section contaning the node coordinates\n");
   }
   else
   {
       fprintf(stderr,"\n\Error finding the start of coordinates from tsp file !!!\n");
       exit(1);
   }

   if ((problem->node = malloc(sizeof(struct point) * problem->n)) == NULL)
       exit(EXIT_FAILURE);
   else
   {
       for (i = 0 ; i < problem->n ; i++)
       {
           fscanf(TSP_file,"%ld %lf %lf", &j, &problem->node[i].x, &problem->node[i].y );
       }
   }
   printf("Number of cities is %ld\n",problem->n);
   printf("\nReading TSP file %s completed successfully \n\n", TSP_filename);
   return problem->node;
}

/*
*  initial ants placement
*/
int init_ants_place(struct TSP_data *problem)
{
   double test;
   test = problem->node[6].x;
   printf("node x: %10.3lf\n", test);
   return 0;
}

/*
*  main program
*/
int main(int argc, char *argv[])
{
   const char *filename;
   struct TSP_data problem;
   struct TSP_data *op;
   double node, x;

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

   //debug
   op = load_TSP_data(&problem, filename);
   //init_ants_place(&op);
   init_ants_place(op);
   return 0;
}

 

και το tsp file

 

>
NAME: berlin52
TYPE: TSP
COMMENT: 52 locations in Berlin (Groetschel)
DIMENSION: 52
EDGE_WEIGHT_TYPE: EUC_2D
NODE_COORD_SECTION
1 565.0 575.0
2 25.0 185.0
3 345.0 750.0
4 945.0 685.0
5 845.0 655.0
6 880.0 660.0
7 25.0 230.0
8 525.0 1000.0
9 580.0 1175.0
10 650.0 1130.0
11 1605.0 620.0 
12 1220.0 580.0
13 1465.0 200.0
14 1530.0 5.0
15 845.0 680.0
16 725.0 370.0
17 145.0 665.0
18 415.0 635.0
19 510.0 875.0  
20 560.0 365.0
21 300.0 465.0
22 520.0 585.0
23 480.0 415.0
24 835.0 625.0
25 975.0 580.0
26 1215.0 245.0
27 1320.0 315.0
28 1250.0 400.0
29 660.0 180.0
30 410.0 250.0
31 420.0 555.0
32 575.0 665.0
33 1150.0 1160.0
34 700.0 580.0
35 685.0 595.0
36 685.0 610.0
37 770.0 610.0
38 795.0 645.0
39 720.0 635.0
40 760.0 650.0
41 475.0 960.0
42 95.0 260.0
43 875.0 920.0
44 700.0 500.0
45 555.0 815.0
46 830.0 485.0
47 1170.0 65.0
48 830.0 610.0
49 605.0 625.0
50 595.0 360.0
51 1340.0 725.0
52 1740.0 245.0
EOF

 

Προφανώς η βλακεία γίνεται εκεί που περνάω το op στο init_ants_place() function

:fear:

Δημοσ.
Μπορείς να κάνεις paste σε spoilers όλο τον κώδικα και το att48.tsp ?

 

Πήρα τον κώδικα του μηνύματος #17 και αφού πρόσθεσα includes, αφαίρεσα τις

... και άλλαξα το return σε struct point* μου κάνει compile και τρέχει κανονικά

αλλά χωρίς ολόκληρο τον κώδικα ίσως να παίχθηκε κάτι.

 

Το return θέλω να γυρνάει τα members του TSP_data, μελλοντικά θα χρειαστούν και τα υπόλοιπα (ΝΑΜΕ, COMMENT, etc) fields που διαβάζει από το *.tsp αρχειο.

Το συγκεκριμένο πρόβλημα με το seg.fault το διόρθωσα αλλά τώρα έχω άλλο seg.fault!!!

 

Λοιπόν κάνω paste όλο τον κώδικα μπας και το βρει κανένας...

 

>
/* Ant Colony Optimization (ACO)
*
*   Author: Dr. Fuzzy
*   August, 2010
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <math.h>

#define LINE_BUFFER_LENGTH  50

long int **distance; /* distance[i][j] matrix, from city[i] to city[j]*/

/*
*  load TSP data
*/
struct point
{
   double x;
   double y;
};

struct TSP_data
{
   char name[LINE_BUFFER_LENGTH];
   char edge_weight_type[LINE_BUFFER_LENGTH];
   long int n;
   struct point *node;
};

struct TSP_data* load_TSP_data(struct TSP_data *problem, const char *TSP_filename)
{
   problem->n=1;
   FILE *TSP_file;
   char buffer[LINE_BUFFER_LENGTH];
   long int i, j;

   if (TSP_filename == NULL)
   {
       fprintf(stderr, "No TSP file found, abort\n");
       exit(1);
   }
   else
   {
       TSP_file = fopen(TSP_filename, "rw");
       assert(TSP_file != NULL);
       printf("\nReading TSP file %s ... \n\n", TSP_filename);
   }

   fscanf(TSP_file, "%s", buffer);
   while (strcmp("NODE_COORD_SECTION", buffer) != 0)
   {
       if (strcmp("NAME:", buffer) == 0)
       {
           fscanf(TSP_file, "%s", buffer);
           strcpy(problem->name, buffer);
           printf("NAME: %s \n", problem->name);
           buffer[0]=0;
       }
       else if (strcmp("COMMENT:", buffer) == 0)
       {
           fgets(buffer, LINE_BUFFER_LENGTH, TSP_file);
           printf("COMMENT: %s", buffer);
           buffer[0]=0;
       }
       else if (strcmp("TYPE:", buffer) == 0 )
       {
           fscanf(TSP_file, "%s", buffer);
           printf("TYPE: %s\n", buffer);
           if (strcmp("TSP", buffer) != 0)
           {
               fprintf(stderr,"\nTSP file is differs from the standard TSPLIB format !!\n");
               exit(1);
           }
           buffer[0]=0;
       }
       else if (strcmp("DIMENSION:", buffer) == 0)
       {
           fscanf(TSP_file, "%ld", &problem->n);
           printf("DIMENSION: %ld\n", problem->n);
           assert (problem->n > 2 && problem->n < 6000);
           buffer[0]=0;
       }
       else if (strcmp("DISPLAY_DATA_TYPE", buffer) == 0)
       {
           fgets(buffer, LINE_BUFFER_LENGTH, TSP_file);
           printf("%s", buffer);
           buffer[0]=0;
       }
       else if (strcmp("EDGE_WEIGHT_TYPE:", buffer) == 0)
       {
           buffer[0]=0;
           fscanf(TSP_file, "%s", buffer);
           printf("EDGE WEIGHT TYPE: %s\n", buffer);
           if (strcmp("EUC_2D", buffer) == 0 )
           {
               //distance = euc_distance;
           }
           else
           {
               fprintf(stderr,"This EDGE WEIGHT TYPE (%s) is not yet implemented in this version !\n",buffer);
               fprintf(stderr,"\nAbort!\n\n",buffer);
               exit(1);
           }
           strcpy(problem->edge_weight_type, buffer);
           buffer[0]=0;
       }
       buffer[0]=0;
       fscanf(TSP_file,"%s", buffer);
   }

   if (strcmp("NODE_COORD_SECTION", buffer) == 0)
   {
       printf("\nFound section contaning the node coordinates\n");
   }
   else
   {
       fprintf(stderr,"\n\Error finding the start of coordinates from tsp file !!!\n");
       exit(1);
   }

   if ((problem->node = malloc(sizeof(struct point) * problem->n)) == NULL)
       exit(EXIT_FAILURE);
   else
   {
       for (i = 0 ; i < problem->n ; i++)
       {
           fscanf(TSP_file,"%ld %lf %lf", &j, &problem->node[i].x, &problem->node[i].y );
       }
   }
   printf("Number of cities is %ld\n",problem->n);
   printf("\nReading TSP file %s completed successfully \n\n", TSP_filename);
   return problem->node;
}

/*
*  initial ants placement
*/
int init_ants_place(struct TSP_data *problem)
{
   double test;
   test = problem->node[6].x;
   printf("node x: %10.3lf\n", test);
   return 0;
}

/*
*  main program
*/
int main(int argc, char *argv[])
{
   const char *filename;
   struct TSP_data problem;
   struct TSP_data *op;
   double node, x;

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

   //debug
   op = load_TSP_data(&problem, filename);
   //init_ants_place(&op);
   init_ants_place(op);
   return 0;
}

 

και το tsp file

 

>
NAME: berlin52
TYPE: TSP
COMMENT: 52 locations in Berlin (Groetschel)
DIMENSION: 52
EDGE_WEIGHT_TYPE: EUC_2D
NODE_COORD_SECTION
1 565.0 575.0
2 25.0 185.0
3 345.0 750.0
4 945.0 685.0
5 845.0 655.0
6 880.0 660.0
7 25.0 230.0
8 525.0 1000.0
9 580.0 1175.0
10 650.0 1130.0
11 1605.0 620.0 
12 1220.0 580.0
13 1465.0 200.0
14 1530.0 5.0
15 845.0 680.0
16 725.0 370.0
17 145.0 665.0
18 415.0 635.0
19 510.0 875.0  
20 560.0 365.0
21 300.0 465.0
22 520.0 585.0
23 480.0 415.0
24 835.0 625.0
25 975.0 580.0
26 1215.0 245.0
27 1320.0 315.0
28 1250.0 400.0
29 660.0 180.0
30 410.0 250.0
31 420.0 555.0
32 575.0 665.0
33 1150.0 1160.0
34 700.0 580.0
35 685.0 595.0
36 685.0 610.0
37 770.0 610.0
38 795.0 645.0
39 720.0 635.0
40 760.0 650.0
41 475.0 960.0
42 95.0 260.0
43 875.0 920.0
44 700.0 500.0
45 555.0 815.0
46 830.0 485.0
47 1170.0 65.0
48 830.0 610.0
49 605.0 625.0
50 595.0 360.0
51 1340.0 725.0
52 1740.0 245.0
EOF

 

Προφανώς η βλακεία γίνεται εκεί που περνάω το op στο init_ants_place() function

:fear:

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

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

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