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

void* pointer σε C


jtsc21

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

Δημοσ.

Καλημερα γραφω σε C το παρακατω αλλα δεν κανει compile.Τι λαθος κανω?:-(

 

 

>
#include <stdio.h>
#include <stdlib.h>
struct lol{int num;};
int main(void)
{void* p;
p=malloc(sizeof(struct lol));
*(struct lol*)p.num=8;
}

Δημοσ.
>
#include <stdio.h>
#include <stdlib.h>
struct lol{int num;};
int main(void)
{struct lol * p;[color="#ff0000"]//μπορει να γινει και με void * αλλα δεν βλέπω το λόγο να μπερδευεσαι[/color]
p=malloc(sizeof(*p)); [color="Red"]αλλα και το p = malloc(sizeof(struct lol)) και το p = (struct lol *)malloc(sizeof(struct lol)) είναι σωστά[/color]
p->num=8; [color="#ff0000"]ή (*p).num = 8;[/color]
}

Δημοσ.

καταρχας ευχαριστω για τις απαντησεις σας

βασικα ομως δε ρωταω αυτο ακριβως.Ρωταω συγκεκριμενα για την υλοποιηση του προγραμματος με void* γιατι μου ειναι καπου απαραιτητο

Δημοσ.
Με cast σε struct lol* εδώ, νομίζω.

σε c++ ειναι υποχρεωτικό το cast, ενώ σε C όχι (το void * μετατρέπετε αυτόματα σε οτιδήποτε χωρις cast).

Γνωμη μου είναι ότι δεν είναι κακό να μπαίνει αλλα ούτε και να μην μπαίνει.

 

---------- Το μήνυμα προστέθηκε στις 14:33 ----------

 

καταρχας ευχαριστω για τις απαντησεις σας

βασικα ομως δε ρωταω αυτο ακριβως.Ρωταω συγκεκριμενα για την υλοποιηση του προγραμματος με void* γιατι μου ειναι καπου απαραιτητο

ενω επιμένεις:

 

( * ((struct lol*)p) ).num=8;

 

(βέβαια αρκεί και το

(*(struct lol *)p).num=8;

αν τα πας καλά με τις προταιρεοτητες)

Δημοσ.
σε c++ ειναι υποχρεωτικό το cast, ενώ σε C όχι (το void * μετατρέπετε αυτόματα σε οτιδήποτε χωρις cast).

Γνωμη μου είναι ότι δεν είναι κακό να μπαίνει αλλα ούτε και να μην μπαίνει.

 

---------- Το μήνυμα προστέθηκε στις 14:33 ----------

 

ενω επιμένεις:

 

( * ((struct lol*)p) ).num=8;

thanks!!!

αυτο ζητουσα!:-)

δεν ειχα βαλει τις "εξωτερικες" παρενθεσεις και δεν εκανε compile:devil:

Δημοσ.
Καλημερα γραφω σε C το παρακατω αλλα δεν κανει compile.Τι λαθος κανω?:-(

 

 

>
#include <stdio.h>
#include <stdlib.h>
struct lol{int num;};
int main(void)
{void* p;
p=malloc(sizeof(struct lol));
*(struct lol*)p.num=8;
}

 

Το νόημα του προγράμματος σου είναι προβληματικό λόγο τις προτεραιότητας των χειριστών (operator precedence).

 

Συγκεριμένα, άλλαξε την γραμμή εισχώρησης σε:

>
((struct lol *)p)->num = 8;
/* αλλιώς:
(*((struct lol*)p)).num = 8;
*/

 

Επίσης μην ξεχνάς ότι η malloc μπορεί να γυρίσει NULL και επίσης να ελευθερώνεις την δεσμευμένη μνήμη με την συνάρτηση free.

Δημοσ.

καταρχας ευχαριστω και παλι ολους για τις απαντησεις σας.

Αλλη μια απορια που προεκυψε ειναι η εξης.

Αν εχω για παραδειγμα

 

>
#include <stdio.h>
#include <stdlib.h>
struct lol1{int a; void* p;};
struct lol2{char b; struct lol2* plol2;};

typedef struct lol1 lol1;
typedef struct lol2 lol2;
int main()
{lol1* l1=malloc(sizeof(lol1));
//και εδω θελω τον void* να γινει δειχτης στην lol2 πως γινετε??
lol1->((lol2*)p)=malloc // ή ((*(lol2*)lol1->p))=malloc(...)???
}

και τα 2 μου βγαζουν errors

Δημοσ.
καταρχας ευχαριστω και παλι ολους για τις απαντησεις σας.

Αλλη μια απορια που προεκυψε ειναι η εξης.

Αν εχω για παραδειγμα

 

>
#include <stdio.h>
#include <stdlib.h>
struct lol1{int a; void* p;};
struct lol2{char b; struct lol2* plol2;};

typedef struct lol1 lol1;
typedef struct lol2 lol2;
int main()
{lol1* l1=malloc(sizeof(lol1));
//και εδω θελω τον void* να γινει δειχτης στην lol2 πως γινετε??
lol1->((lol2*)p)=malloc // ή ((*(lol2*)lol1->p))=malloc(...)???
}

και τα 2 μου βγαζουν errors

 

υπάρχουν πολλές λύσεις και δεν είναι απαραίτητο να δουλέψεις όπως κάνεις τώρα με τα void *. Αυτα χρησιμοποιούνται απο έμπειρους μόνο σε ειδικές συνθήκες. Γιατί να παρακάμψεις όλες τις προστασίες της γλώσσας και να ρισκάρεις να κάνεις λάθη;

 

>
struct lol1;//forward δήλωση του lol1,2
struct lol2;

struct lol1 {int a; struct lol2* p;};
struct lol2 {char b; struct lol2* plol2;};
...

lol1->p=malloc(sizeof (lol2));

ακόμα και void *  να είναι, θα αρκούσε το απλό lol1->p = malloc
αλλά δοκίμασες μόνο με τα cast και όχι με απ'ευθείας αναθεση

Δημοσ.

βασικα ομως μολις το κανω αυτο lol1->p=malloc(sizeof(lol2))

 

παω μετα να παρω προσβαση στο struct lol2

lol1->p->b=...

και μου βγαζει ο compiler(gcc)

1.dereferencing ‘void *’ pointer

2.request for member ‘grade’ in something not a structure or union

που σημαινει οτι κατι δε κανω σωστα..

και ακομη αν μπορεις, γινετε να μου εξηγησεις και πως το κανω χρησιμοποιωντας casting (πιο πολυ αυτο για να μου φυγει η περιεργια) η να μου δωσεις καποιο link που να τα εξηγει?

 

και παλι thanks για το χρονο σου

Δημοσ.
>
#include <stdio.h>
#include <stdlib.h>

struct lol1 {
 int a;
 void* p;
};

struct lol2 {
 char b;
 struct lol2* plol2;
};

typedef struct lol1 lol1;
typedef struct lol2 lol2;

void lol2func (lol2 * p)
{
 fprintf(stdout, "b = %c\n", p->;
}

int main()
{
 lol1 * l1 = (lol1 *) malloc(sizeof(lol1));
 lol2 l2 = {'a',  NULL};

 l1->p = (void *)malloc(sizeof(lol2));
 l1->p = (void *)&l2;
 lol2func((lol2*)l1->p);

 return 0; 
}

Δημοσ.
βασικα ομως μολις το κανω αυτο lol1->p=malloc(sizeof(lol2))

 

παω μετα να παρω προσβαση στο struct lol2

lol1->p->b=...

και μου βγαζει ο compiler(gcc)

1.dereferencing ‘void *’ pointer

2.request for member ‘grade’ in something not a structure or union

που σημαινει οτι κατι δε κανω σωστα..

και ακομη αν μπορεις, γινετε να μου εξηγησεις και πως το κανω χρησιμοποιωντας casting (πιο πολυ αυτο για να μου φυγει η περιεργια) η να μου δωσεις καποιο link που να τα εξηγει?

 

και παλι thanks για το χρονο σου

 

αν είχες γράψει τις forward δηλώσεις όπως έγραψα στην απαντηση μου δεν θα είχες το πρόβλημα αυτο. Είτε το χρησιμοποιείς με void * είτε με τις forward δηλώσεις ο παραγόμενος κώδικας σε γλώσσα μηχανης είναι ο ίδιος ακριβώς.

 

εσυ έχεις δηλώσει το lol1->p να είναι δείκτης σε μια θέση raw μνήμης (αδόμητης). Πως να σου κάνει ο compiler το lol1->p->b ενω η αδόμητη μνημη (void *) δεν έχει members (όπως το b που προσπαθείς να προσπελάσεις), ούτε μέγεθος γνωστό δεν έχει

 

στην περίπτωση που σου είχα πεί με forward δήλωση, το p δεν θα ήταν αδόμητο αλλά δείκτης σε lol2 αρα θα είχε member b.

 

Απο void * τωρα:

Εστω ότι έχεις έναν δείκτη void *p και θές να τον κάνεις struct lol2:

>
((lol2 *)p)->b

δηλαδή πρέπει να μετατρέψεις το p σε δεικτη lol2 απο δεικτη void *. Το αποτέλεσμα του

((lol2 *)p)

είναι δείκτης σε lol2 αρα έχει members τα μέλη της lol2.

 

Αλλο παραδειγμα:

>
int a = 3;
void *p = &a;//το p δείχνει στη θέση που έχει αποθηκευτεί το a, αλλά το p δεν ξερει αν εκει ειναι αποθηκευμένος ακεραιος ή κανένα megabyte δεδομένα.
*p = 7;//δεν γίνεται, το *p δεν μπορεί να οριστεί διότι είναι αδόμητη μνήμη αρα αγνωστης διαστασης/τυπου
((int*)p)  //τωρα έγινε δεικτης σε ακέραιο (reference to int)
* ((int*)p) //τωρα έγινε ο ακέραιος (έγινε dereference)
*((int *)p) = 2;//τωρα τα 3 γίναν 2:-D

 

K&R είναι η βίβλος αν ψάχνεις την τρίχα απο τοσο χαμηλου επιπέδου θέματα.

Θα βρείς 100δες χιλιάδες σελίδες στο google με παραδείγματα για pointers/examples/tutorials.

  • 3 εβδομάδες αργότερα...
Δημοσ.

καλησπερα και παλι..

 

αν εχω :

>
#include <stdio.h>
#include <stdlib.h>
typedef struct list list;
struct list{...
                 list* next;
};

int main(void)
{void* p;//θελω υποχρεωτικα να οριζεται void*
p=(void*)malloc(sizeof(list));
...
[color="Red"] ((list*)p)=((list*)p)->next;//θελω να παω στον επομενο κομβο[/color]
}

 

στην κοκκινη γραμμη μου βγαζει error...:cry:

οταν ομως γραψω p=((list*)p)->next; τοτε κανει compile κανονικα...

 

μπορει να μου εξηγησει καποιος πως ειναι αυτο δυνατον?

γιατι το εκανα ψιλομπακαλιστικα αλλα θελω να καταλαβω και τον λογο;)

Δημοσ.

Αμα σε μπερδευει ο pointer (void*) βαλε κατι αλλο. Βαλε long ή int τσεκαρε το παρακατω

>#include <stdio.h>
#include <stdlib.h>
#define D(name) ((Obj*)name)
#define NoD(name) (*(D(name)))
struct Obj
{
int a,b,c;
};
typedef struct Obj Obj;

void main()
{
//alloc mem
   int ptr = (int)malloc(sizeof(Obj));
//add dynimic
D(ptr)->a=1;
D(ptr)->b=5;
D(ptr)->c=9;


//get dynimic 
printf("%d,%d,%d\n",D(ptr)->a,D(ptr)->b,D(ptr)->c);
//get no dynimic (den kserw pws legete)
printf("%d,%d,%d\n",NoD(ptr).a,NoD(ptr).b,NoD(ptr).c);
getchar();


}

  • Moderators
Δημοσ.
καλησπερα και παλι..

 

αν εχω :

>
#include <stdio.h>
#include <stdlib.h>
typedef struct list list;
struct list{...
                 list* next;
};

int main(void)
{void* p;//θελω υποχρεωτικα να οριζεται void*
p=(void*)malloc(sizeof(list));
...
[color="Red"] ((list*)p)=((list*)p)->next;//θελω να παω στον επομενο κομβο[/color]
}

 

στην κοκκινη γραμμη μου βγαζει error...:cry:

οταν ομως γραψω p=((list*)p)->next; τοτε κανει compile κανονικα...

Νομίζω ότι αυτό γίνεται γιατί απλά αυτή η σύνταξη (στην κόκκινη γραμμή) δεν επιτρέπεται (casting σε lvalue) μια και το αριστερό σκέλος αντιπροσωπεύει μια μεταβλητή (μια θέση στη μνήμη).

 

Είναι πιο σωστό να το γράψεις χωρίς το casting στο αριστερό p έτσι και αλλιώς. Ο p ως δείκτης σε void μπορεί να δείξει το οτιδήποτε, και με την έκφραση (list*)p)->next; θα δείξει σωστά στο επόμενο στοιχείο της λίστας.

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

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

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