c - Kernel Device Driver "dereferencing 'void *' pointer -


i learning how write device drivers linux, , have question regarding use of generic data structures.

i have assignment, have functional...so i'm not asking homework...

this assignment requires device able enqueue , dequeue elements fifo buffer. made buffer "generic" element size used(and specified @ runtime). source included below(note not kernel version, error same)...kernel version requires kmalloc, copy_to/from_user() etc...

#include <stdio.h> #include <stdlib.h> #include <string.h>  struct rb_buffer {     void* rbdata;     unsigned int getindex;  //index remove element     unsigned int putindex;  //index put element @     unsigned int capacity;  //max elements buffer holds     unsigned int elemcount; //num elements inserted     unsigned int elemsize;  //size of each element };  void* rb_kcreate(int numelements, unsigned int elementsize); int putring(struct rb_buffer *rbptr, void* data); int getring(struct rb_buffer *rbptr, void* data);   //creates ring buffer of specified number of elements , element size. //returns void* pointer pointing rb_buffer struct. pointer can //then used on putring , getring functions. void* rb_kcreate(int numelements, unsigned int elementsize) {     struct rb_buffer *newbuf = malloc(sizeof(struct rb_buffer));     if(newbuf == null) return 0;     newbuf->rbdata = (void*)malloc(elementsize*numelements);//, gfp_kernel);     if(newbuf->rbdata == null)     {         free(newbuf);         return 0;     }     newbuf->capacity = numelements;     newbuf->elemsize = elementsize;         newbuf->getindex = 0;         newbuf->putindex = 0;         newbuf->elemcount = 0;      return newbuf; }  //puts element in buffer. returns -1 if full, 0 on success //send data through void* data argument int putring(struct rb_buffer *rbptr, void* data) {     int = 0;     if ( rbptr->elemcount >= rbptr->capacity )         return -1;      memcpy(&rbptr->rbdata[rbptr->putindex * rbptr->elemsize], data, rbptr->elemsize);     rbptr->putindex++;     if (rbptr->putindex >= rbptr->capacity )         rbptr->putindex = 0;     rbptr->elemcount++;      return 0; }  //removes element in buffer. returns -1 if empty, 0 on success //data returned through data pointer int getring(struct rb_buffer *rbptr, void *data) {     if ( !rbptr->elemcount )         return -1;       rbptr->elemcount--;     memcpy(data, &rbptr->rbdata[rbptr->getindex * rbptr->elemsize], rbptr->elemsize);     rbptr->getindex++;     if ( rbptr->getindex >= rbptr->capacity )         rbptr->getindex = 0;      return 0;  } 

when compile kernel module, warnings:

kringbuf_generic.c:53: warning: dereferencing ‘void *’ pointer kringbuf_generic.c:72: warning: dereferencing ‘void *’ pointer

the error occurs here in putring(in memcpy)

if ( rbptr->elemcount >= rbptr->capacity )             return -1;          memcpy(&rbptr->rbdata[rbptr->putindex * rbptr->elemsize], data, rbptr->elemsize);         rbptr->putindex++; 

and here in getring, in memcpy() function

rbptr->elemcount--;         memcpy(data, &rbptr->rbdata[rbptr->getindex * rbptr->elemsize], rbptr->elemsize);         rbptr->getindex++; 

obviously since kernel module, not known use this, , fixing buffer element size limit usage of buffer.

is there way rid of warnings? or there fundamental thing should doing differently when developing such code?

i think problem code:

rbptr->rbdata[rbptr->getindex * rbptr->elemsize] 

is trying index array pointed @ rbdata, of type void *. can't meaningfully make operation work on void* pointer, because indexing array in c requires know size of elements in array, , definition void* pointer elements of unknown type.

most compilers let anyway implicitly casting void* char* , reading raw byte values. however, it's not idea this, since operation isn't well-defined.

to fix , silence warning, consider explicitly typecasting rbdata field char* before dereferencing it:

((char *)rbptr->rbdata)[rbptr->getindex * rbptr->elemsize] 

or alternatively, store char* in struct avoid having repeatedly typecast.

hope helps!


Comments

Popular posts from this blog

apache - Add omitted ? to URLs -

redirect - bbPress Forum - rewrite to wwww.mysite prohibits login -

php - How can I stop spam on my custom forum/blog? -