chiossif Δημοσ. 30 Νοεμβρίου 2006 Δημοσ. 30 Νοεμβρίου 2006 Χαίρομαι όταν μαθαίνω: "... It's not necessary (given that coercion of void * to ALMOSTANYTYPE * is automatic), and possibly harmful if malloc, or a proxy for it, fails to be declared as returning void *. ..." Μπράβο dop, με έπεισες (και) σε αυτό...
parsifal Δημοσ. 30 Νοεμβρίου 2006 Δημοσ. 30 Νοεμβρίου 2006 On the other hand, pre-ANSI, the cast was necessary, and it is in C++ also Εμένα πάλι με προβληματίζει αυτό. Δλδ αν θες να γράψεις κώδικα που να είναι reusable σε C++, θα πρέπει να κάνεις casting? Τελικά, τί να κάνει κανείς? Πού βαδίζουμε? Γιατί δε μου "πέφτει" το Τζόκερ? Γιατί...?
dop Δημοσ. 1 Δεκεμβρίου 2006 Δημοσ. 1 Δεκεμβρίου 2006 @chiossif: αυτό κάνω για να ζήσω @parifal: άμα θέλεις να κάνεις C κώδικα να κάνει compile σε C++ compiler τότε πρέπει να κάνεις casting. Φυσικά, αυτό είναι τελείως άχρηστο: αν θέλεις να γράφεις C, τότε να την κάνεις compile με C compiler, ειδάλλως γράψε C++. Αν από την άλλη απλώς θέλεις να βάλεις κάποιο κομμάτι C μέσα στο C++ πρόγραμμά σου, τότε η extern "C" {} είναι αυτό που σου χρειάζεται.
Directx Δημοσ. 1 Δεκεμβρίου 2006 Δημοσ. 1 Δεκεμβρίου 2006 Για την παλιά σχολή είναι τουλάχιστον θρησκευτικό ζήτημα το casting στην malloc (θα το βρεις σε παλαιά βιβλία) από την άλλη πλευρά τα πρότυπα εξελίσσονται οπότε ο dop έχει δίκιο.
profitis Δημοσ. 13 Δεκεμβρίου 2006 Δημοσ. 13 Δεκεμβρίου 2006 Για να επαναφέρω λιγάκι το θέμα...Το βρήκα απο search το θέμα αλλα μόνο γι΄αυτο δεν κατάλαβα διαβάζοντας εδώ... Λοιπον, θέλω να κατασκεύαζω έναν δυσδιάστατο που οι διαστάσεις του κάθε φορα θα ειναι μεταβλητές(m,n που θα διαβάζονται απο ένα txt αρχείο). Αυτο προφανώς γίνεται με malloc.Για έναν μονοδιάστατο πίνακα κατάλαβα πως γίνεται(ουσιαστιικά μόνο με έμμεση διευθυνδιοδότηση (*) γίνεται χρήση-προσπέλαση-δουλεια με τον πίνακα)Για τον δυσδιάστατο όμως πως θα το κάνω;θα πρέπει να κάνω κάποια ειδική δήλωση στην malloc ή να χρησιμοποιηθεί κάποια ειδική σημειογραφία με τους δείκτες; Τhanks εκ των προτέρων!!!
dop Δημοσ. 13 Δεκεμβρίου 2006 Δημοσ. 13 Δεκεμβρίου 2006 Μπορείς με το εξής: > typedef int data_t; size_t m, n, i; data_t **array; array = malloc(m*sizeof *array); if (array==NULL) /* error handling */ for (i=0; i<m; i++) { array[i] = malloc(n*sizeof **array); if (array[i]==NULL) { size_t j; for (j=0; j<i; j++) free(array[j]); free(array); /* error message and exit? */ } } Όσο αυξάνονται οι διαστάσεις, τόσο θα αυξάνονται και τα loops που θα φτιάχνουν τον πίνακα.
profitis Δημοσ. 13 Δεκεμβρίου 2006 Δημοσ. 13 Δεκεμβρίου 2006 Thanks dop... Πες οτι θέλω να προσπελάσω ένα μέλος του δυσδιάστατου πίνακα:Aυτο θα γίνεται με σημειολογία δεικτών;(Προφανώς)Δηλαδή για το πρώτο πρώτο στοιχείο του πίνακα αρκεί να γράφω **array[0][0];Εδωπέρα οι δείκτες θα είναι όταν βάζουμε μονο αστεράκι; Η C εσωτερικά σαν μονοδυάστατο τον χειρίζεται;
chiossif Δημοσ. 13 Δεκεμβρίου 2006 Δημοσ. 13 Δεκεμβρίου 2006 ...κώδικα σε παλαιότερο μύνημα στο ίδιο θέμα: > #include <stdio.h> #include <stdlib.h> int main (void) { int n, i, j; double i1, **a, **b, *c; /* Get array dimension */ do{ printf ("\nEnter matrix dimension N>0 : "); scanf ("%d",&n); }while(n<1); /* Allocate memory to a as a double array NxN */ if ((a=(double **)malloc(n*sizeof(double *)))==NULL){ printf("\nNot enough memory avaliable.\n"); exit(1); } for(i=0;i<n;i++){ if ((a[i]=(double *)malloc(n*sizeof(double)))==NULL){ printf("\nNot enough memory avaliable.\n"); exit(1); } } /* Fills a with data */ for (i=0;i<n;i++){ i1=(double)i+1; a[i][i]=i1/i1; for (j=0;j<i;j++) a[j][i]=a[i][j]=i1/(j+1); } /* Displays a's data */ printf("\nA array:\n"); for (i=0;i<n;i++){ for (j=0;j<n;j++) printf(" %7.3lf", a[i][j]); printf("\n"); } /* Allocate memory to b as a double array NxN */ if ((b=(double **)malloc(n*sizeof(double *)))==NULL){ printf("\nNot enough memory avaliable.\n"); exit(1); } for(i=0;i<n;i++){ if ((b[i]=(double *)malloc(n*sizeof(double)))==NULL){ printf("\nNot enough memory avaliable.\n"); exit(1); } } /* Copies a to b */ memcpy(b,a,n*n*sizeof(double)); /* Displays b's data */ printf("\nB array:\n"); for (i=0;i<n;i++){ for (j=0;j<n;j++) printf(" %7.3lf", a[i][j]); printf("\n"); } /* Allocate memory to c as a double vector N */ if ((c=(double *)malloc(n*sizeof(double)))==NULL){ printf("\nNot enough memory avaliable.\n"); exit(1); } /* Copy and display a rows to c */ for(i=0;i<n;i++){ memcpy(c,a[i],n*sizeof(double)); printf("\nC vector (with %d row data):\n", i); for (j=0;j<n;j++) printf(" %7.3lf", c[j]); printf("\n"); } /* Free a array */ for(i=0;i<n;i++) free(a[i]); free(a); /* Free b array */ for(i=0;i<n;i++) free(b[i]); free(; /* Free c vector */ free(c); return 0; } Συνιστώ, δεύτερος, την χρήση typedef και size_t δηλώσεων όπως στον κώδικα του dop απλά δεν τις χρησιμοποίησα εδώ. Νομίζω όμως ότι κάλυψα το ερώτημά του profitis. Υπάρχει ένα warning (μόνο)... dop, φίλοι, αναμένω τα σχόλιά σας.
dop Δημοσ. 13 Δεκεμβρίου 2006 Δημοσ. 13 Δεκεμβρίου 2006 1. Η memcpy() ζει στο string.h. Άρα, #include <string.h> 2. Είπαμε, όχι casting στην malloc(). Και ο κώδικάς σου είναι το καλύτερο παράδειγμα: τι θα γίνει αν αντί για double i1, **a, **b, *c; έχουμε my_super_big_struct i1, **a, **b, *c; ? Πόσες φορές θα θυμηθούμε να αλλάξουμε τα πάντα; 3. Τρώω και ένα segmentation fault...
chiossif Δημοσ. 14 Δεκεμβρίου 2006 Δημοσ. 14 Δεκεμβρίου 2006 ...με τις διορθώσεις από dop: > /* array2d_malloc.c: malloc(usage, casting) memcpy... v0.0.3 */ #include <stdio.h> #include <stdlib.h> #include <string.h> int main (void) { int n, i, j; double i1, **a, **b, *c; /* Get array dimension */ do{ printf ("\nEnter matrix dimension N>0 : "); scanf ("%d",&n); }while(n<1); /* Allocate memory to a as a double array NxN */ if ((a=malloc(n*sizeof(double *)))==NULL){ printf("\nNot enough memory avaliable.\n"); exit(1); } for(i=0;i<n;i++){ if ((a[i]=malloc(n*sizeof(double)))==NULL){ printf("\nNot enough memory avaliable.\n"); exit(1); } } /* Fills a with data */ for (i=0;i<n;i++){ i1=(double)i+1; a[i][i]=i1/i1; for (j=0;j<i;j++) a[j][i]=a[i][j]=i1/(j+1); } /* Displays a's data */ printf("\nA array:\n"); for (i=0;i<n;i++){ for (j=0;j<n;j++) printf(" %7.3lf", a[i][j]); printf("\n"); } /* Allocate memory to b as a double array NxN */ if ((b=malloc(n*sizeof(double *)))==NULL){ printf("\nNot enough memory avaliable.\n"); exit(1); } for(i=0;i<n;i++){ if ((b[i]=malloc(n*sizeof(double)))==NULL){ printf("\nNot enough memory avaliable.\n"); exit(1); } } /* Copies a to b */ memcpy(b,a,n*n*sizeof(double)); /* Displays b's data */ printf("\nB array:\n"); for (i=0;i<n;i++){ for (j=0;j<n;j++) printf(" %7.3lf", a[i][j]); printf("\n"); } /* Allocate memory to c as a double vector N */ if ((c=malloc(n*sizeof(double)))==NULL){ printf("\nNot enough memory avaliable.\n"); exit(1); } /* Copy and display a rows to c */ for(i=0;i<n;i++){ memcpy(c,a[i],n*sizeof(double)); printf("\nC vector (with %d row data):\n", i); for (j=0;j<n;j++) printf(" %7.3lf", c[j]); printf("\n"); } /* Free a array */ for(i=0;i<n;i++) free(a[i]); free(a); /* Free b array */ for(i=0;i<n;i++) free(b[i]); free(; /* Free c vector */ free(c); return 0; } 0. Φίλε dop, όπως βλέπεις έχω διορθώσει ΚΑΙ ΤΟ int main(void) 1. Δίκαιο έχεις το'χα ξεχάσει. Έγινε. 2. ΟΚ και με αυτό. Το'χα παραδεχτεί απλώς ξέχασα να βγάλω το casting τα υπόλοιπα έγιναν copy paste (σε forum είμαστε...) 3. Αν το δοκιμάσεις με τιμή έως 8 όλα πάνε καλά (τουλάχιστον στην gcc (GCC) 4.1.0 (SUSE Linux) μου). Αν το δοκιμάσεις με τιμή 9 (και πάνω) όμως... Δοκίμασες να σχολιάσεις τo free "block" στο τέλος; Μήπως τελικά μαζί με το casting πρέπει να καταργήσουμε και τα free; ( Που'ναι το λάθος...ΟΕΟ... )
Directx Δημοσ. 14 Δεκεμβρίου 2006 Δημοσ. 14 Δεκεμβρίου 2006 Δοκιμάζοντας τον κώδικα σου στην CodeGear Turbo C++ Express για MS-Windows (είσοδος 8), δίχως να τον έχω μελετήσει καθόλου και με ενεργοποιημένο τον εσωτερικό ανιχνευτή σφαλμάτων διαχείρισης μνήμης (CodeGuard) του compiler μου, έλαβα σφάλμα Access overrun στην εντολή memcpy(b,a,n*n*sizeof(double *)); η οποία δοκιμάζει να προσπελάσει 256 bytes από το heap που είναι μόλις 32 bytes long (δοκίμασε να αλλάξεις το "*n*n*sizeof" σε "n*sizeof" ή καλύτερα αφαίρεσε την εντελώς). Υ.Γ. 1. Θα μου πεις πως μπορεί να πέφτει έξω ο ανιχνευτής μου. 2. Στην εκτύπωση των περιεχομένων του b άλλαξε το "printf(" %7.3lf", a[j]);" σε "printf(" %7.3lf", b[j]);". 3. Φαίνεται πως υπάρχουν ορισμένα σφάλματα στην αποδέσμευση μνήμης (free(b)), ο λόγος προέρχεται από το ότι η "memcpy(b,a,n)" © ή η "CopyMemory(b,a,n)" (Windows API) στην περίπτωση μας (**a,**b) αντικαθιστά συνολικά τις διευθύνσεις του b[]([]) με εκείνες του a[]([]) οπότε η free(b) δοκιμάζει να αποδεσμεύσει τις διευθύνσεις της a[]([]) αφήνοντας τις b=malloc μη αποδεσμευμένες. Το πρόβλημα είναι μεγαλύτερο αλλά γίνεται αμέσως αντιληπτό στις κλήσεις free(b); -δοκίμασε να δεις τις διευθύνσεις των a & b μετά την memcpy με printf "%X\n",&a[j] κτλ. σε εμένα είναι ίδιες. Ο παρακάτω κώδικας δουλεύει σωστά με τον compiler μου και τον CodeGuard (έχω αφαιρέσει την memcpy(b,a,n) η οποία στην αρχική μορφή της φαίνεται να δημιουργεί προβλήματα σε multi-dimensional arrays, προς χάριν δυο αργών for). > /* array2d_malloc.c: malloc(usage, casting) memcpy... v0.0.3 */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <conio.h> int main (void) { int n, i, j; double i1, **a, **b, *c; /* Get array dimension */ do{ printf ("\nEnter matrix dimension N>0 : "); scanf ("%d",&n); }while(n<1); /* Allocate memory to a as a double array NxN */ if ((a=malloc(n*sizeof(double *)))==NULL){ printf("\nNot enough memory avaliable.\n"); exit(1); } for(i=0;i<n;i++){ if ((a[i]=malloc(n*sizeof(double)))==NULL){ printf("\nNot enough memory avaliable.\n"); exit(1); } } /* Fills a with data */ for (i=0;i<n;i++){ i1=(double)i+1; a[i][i]=i1/i1; for (j=0;j<i;j++) a[j][i]=a[i][j]=i1/(j+1); } /* Displays a's data */ printf("\nA array:\n"); for (i=0;i<n;i++){ for (j=0;j<n;j++) printf(" %7.3lf", a[i][j]); printf("\n"); } printf(" | HIT KEY TO CONTINUE |"); getch(); /* Allocate memory to b as a double array NxN */ if ((b=malloc(n*sizeof(double *)))==NULL){ printf("\nNot enough memory avaliable.\n"); exit(1); } for(i=0;i<n;i++){ if ((b[i]=malloc(n*sizeof(double)))==NULL){ printf("\nNot enough memory avaliable.\n"); exit(1); } } /* Copies a to b */ for(i=0;i<n;i++) for(j=0;j<n;j++) b[i][j] = a[i][j]; /* memcpy(b,a,n*sizeof(double *)); */ /* Displays b's data */ printf("\nB array:\n"); for (i=0;i<n;i++){ for (j=0;j<n;j++) printf(" %7.3lf", b[i][j]); printf("\n"); } printf(" | HIT KEY TO CONTINUE |"); getch(); /* Allocate memory to c as a double vector N */ if ((c=malloc(n*sizeof(double)))==NULL){ printf("\nNot enough memory avaliable.\n"); exit(1); } /* Copy and display a rows to c */ for(i=0;i<n;i++){ memcpy(c,a[i],n*sizeof(double)); printf("\nC vector (with %d row data):\n", i); for (j=0;j<n;j++) printf(" %7.3lf", c[j]); printf("\n"); } printf(" | HIT KEY TO CLEANUP |"); getch(); /* Free a array */ for(i=0;i<n;i++) free(a[i]); free(a); /* Free b array */ for(i=0;i<n;i++) free(b[i]); free(; /* Free c vector */ free(c); printf("\n | HIT KEY TO QUIT |"); getch(); return 0; } Καλή συνέχεια!
dop Δημοσ. 14 Δεκεμβρίου 2006 Δημοσ. 14 Δεκεμβρίου 2006 Δεν θα έπρεπε να υπάρχει πρόβλημα με την memcpy(). Αντιγράφω από την man page στο linux (που δεν έχει και τις καλύτερες man pages): The memcpy() function copies n bytes from memory area src to memory area dest. The memory areas should not overlap. Use memmove(3) if the memory areas do overlap. Θεωρητικά δεν πρέπει να υπάρχει πρόβλημα - και πρακτικά δεν έχει, αφού την έχω χρησιμοποιήσει άπειρες φορές. Αλλού είναι το πρόβλημα - μόλις βρω λίγο χρόνο θα το κοιτάξω.
chiossif Δημοσ. 14 Δεκεμβρίου 2006 Δημοσ. 14 Δεκεμβρίου 2006 Μπράβο... Πλησίασες αρκετά... Συνέχισε να το ψάχνεις αν έχεις χρόνο. @dop & other "Programming Insomniacs": Πρώτα όλα τα άλλα (οικογένεια, σπουδές, ταίρια, ότι θέλετε) και μετά το forum. Απλά πείτε μου: "Να το πάρει το ποτάμι;" Είναι απλό, είναι μπροστά σας ΑΛΛΑ... (@all: Αν το βρεις μην το μαρτυρίσεις αμέσως... Από την άλλη, μην αφιερώσεις πάνω από 30 λεπτά... Νομίζω ότι δεν αξίζει περισσότερο χρόνο)
pitsis Δημοσ. 14 Δεκεμβρίου 2006 Δημοσ. 14 Δεκεμβρίου 2006 @chiossif to source compliled sto m$ vc++ 6.0 xtupaei akoma kai me n<8 baraei logw free, opws leei o directX, kai episis bgazei bullshit (akoma kai me n<8) <flame> mhpws einai pio e3upnos apo to ansi gcc? </flame> 8a apanel8w...
Directx Δημοσ. 14 Δεκεμβρίου 2006 Δημοσ. 14 Δεκεμβρίου 2006 Μπράβο... Πλησίασες αρκετά... Συνέχισε να το ψάχνεις αν έχεις χρόνο. Φίλε chiossif, Είναι τόσο μικρά .. * και όμως είναι τόσο σημαντικά, κοινά αλλά διαφορετικά * .. το ένα κοιτάζει ανατολικά και το άλλο δυτικά.. Δεν λέω τίποτε περισσότερο.. Τα υπόλοιπα τα αφήνω σε σένα -όποτε κρίνεις σκόπιμο.
Προτεινόμενες αναρτήσεις
Αρχειοθετημένο
Αυτό το θέμα έχει αρχειοθετηθεί και είναι κλειστό για περαιτέρω απαντήσεις.