-6

I received data from some other function to myfunction(const void *data) where pointer data stores the values like {0,0,0,0,0,0,0,40,20,0,0,0,0,0,0}.

I want to access just values from {40,20,0,0,0,0,0,0} and convert into a double type value that should give 8.0 . For accessing and conversion to double type I have tried pointer to double:

double* dptr;
dptr=&(*data+8);
dptr;

that was giving error like

"error: ‘const void*’ is not a pointer-to-object type"

bolov
  • 72,283
  • 15
  • 145
  • 224

4 Answers4

2

In C you cannot de-reference a void pointer. So you can type cast the void pointer and use it. something like this dptr=((double*)data+8); So the data which is void is considered as a double pointer now.

Ginu Jacob
  • 1,588
  • 2
  • 19
  • 35
  • @ Ginu Jacob i want these 8 bytes 40,20,0,0,0,0,0,0 to double value 8.0 i tried your suggestion but still having problem because confusion is when i am assigning the address of 8th element, will dptr also take the other values to provide a double type result like (0x4020000000000000) 8.0. can you please provide some suggestion.. – user3863496 Jul 22 '14 at 12:34
  • It depends on your input array. Lets say if your array {0,0,0,0,0,0,0,40,20,0,0,0,0,0,0} is not of double it will give you wrong results. This is because when you say a void pointer, to C it is just an address of no-sense. It considers the void pointer as the starting address and interpret the data according to the type which you are mentioning. – Ginu Jacob Jul 22 '14 at 13:02
1

Edit Your post is very unclear. Assuming data is actually a pointer to an array of double the solution is even simpler:

double * pd = static_cast<double const *>(data);
double d0 = pd[0];
double d1 = pd[1];

or (C):

double * pd= (double const *)(data);
double d0 = pd[0];
double d1 = pd[1];

You cannot perform pointer arithmetics and dereferencing on void * so *data or data + 8 are invalid.

I don’t understand exactly what you are trying to do, but here is how you access data in your array:

Assuming the data stored is actually int, to access the 8th element and convert it into double you should write:

double el = static_cast<double>*(static_cast<int const *>(data) + 8));

better yet:

int *p = static_cast<int const *>(data);
double el = static_cast<double>(p[8]);

Please note that is is really important that you convert data to the original pointer type . In my example I used int but you should replace it with what your data actually is.

On that note, if what you are showing as {0,0,0,0,0,0,0,40,20,0,0,0,0,0,0} are actually bytes, then the original pointer type is char * and you should convert to char *.


To clarify furthermore converting data from pointers:

Let’s say you have a pointer to int:

int i  = 24;
int *pi = &i;

How would you convert to double the data found on address pi?

// wrong:
double *pd = &i;
cout << *pd << endl;

That is wrong because what you do is converting the pointer type and not the actual data. In effect you interpret the bit pattern found at address pi as a bit pattern representing a double. But that bit pattern represents and int.

What you need to do is retrieve the data as it is: an int and then convert the int to double:

int x = *pi;
double d = (double) x;
bolov
  • 72,283
  • 15
  • 145
  • 224
  • This is not correct. If you cast to another type different of char, and add some offset (like your +8), the compiler will jump 8*sizeof(int) bytes, which will lead you outside the vector! The correct casting for performing pointer arithmetic from a void* is ALWAYS through a char* , so the offset will be counted in bytes: double el = static_cast*(static_cast(data) + 8)); – LoPiTaL Jul 22 '14 at 07:59
  • @LoPiTaL it is correct if the data within the array is `int`. Then an element is `sizeof(int)` bytes long and the offset is correct. – bolov Jul 22 '14 at 08:00
  • @LoPiTaL Since the OP says only `void *` and then shows something like `{0, 0, 8, 0}` I don’t know what the elements are. If he is showing bytes, then yes, you should convert to `char *`, but my post is still correct as the original type of the array is `char *` and I explicitly state that he should convert to the original type. I used `int` as a placeholder. – bolov Jul 22 '14 at 08:04
  • Ok, I removed the downvote, since the OP does not explain correctly his data type. Anyway, it seems that those are bytes, since 0x4020000000000000 is actually an 8.0 value. – LoPiTaL Jul 22 '14 at 08:08
  • @LoPiTaL yeah, really bad question. – bolov Jul 22 '14 at 08:09
0

You cannot perform pointer arithmetic in void pointers, since you don't know the size of the inner data (as it says, it is void). You have to typecast it to a type with a known size.

The correct typecasting and pointer arithmetic is as follows (using old C conversions):

char * ptr=(char *)data;
double * myDoublePtr=(double *)(ptr+8);
double myDouble=*myDouble;

Or, as you have two doubles consecutive:

double * ptr=(double *)data;
double myDouble=*(ptr+1); //This will access the second double.

This is because an offset in pointer arithmetics will perform a jump of offset*sizeof(type) bytes, so in a char type, the number of bytes jumped will actually be the same as your offset.

LoPiTaL
  • 2,495
  • 16
  • 23
  • my received data is bytes i want these 8 bytes 40,20,0,0,0,0,0,0 to double value 8.0 i tried your suggestion but still having problem because when i am assigning the address of 8th element, will ptr also take the other values to provide a double type result like (0x4020000000) 8.0. can you please provide some suggestion.. i want to access from 8th element that is 40 to last element and then convert whole eight elements into a double value. – user3863496 Jul 23 '14 at 05:35
0
#include <stdio.h>
#include <string.h>

double myfunction(const void *data){
    double v;
    memcpy(&v, data, sizeof(v));
    return v;
}
int main (int argc, char *argv[]) {
    unsigned char data[] = {0x40,0x20,0,0,0,0,0,0};
    int i, len = sizeof(data);

    //reverse data If necessary
    for(i=0;i<len/2;++i){
        unsigned char c = data[i];
        data[i] = data[len -1 -i];
        data[len -1 -i] = c;
    }
    double v;
    v = myfunction(data);
    printf("%f\n", v);//8.000000
    return 0;
}
BLUEPIXY
  • 39,699
  • 7
  • 33
  • 70
  • As i mentioned @BLUEPIXY in my question i want to access values from (40,20,0,0,0,0,0,0) how can i store them automatically in some other variable and then use memcpy for that other variable will that work .. and also i – user3863496 Jul 23 '14 at 07:15
  • @user3863496 There is a need to reverse the sequence of data, depending on the endianness of the machine to be used by you. – BLUEPIXY Jul 23 '14 at 07:37
  • can you provide me some help because actual data i am receiving storing in const void *data is {0,0,0,0,0,0,0,40,20,0,0,0,0,0,0} then i stored the values from {40,20,0,0,0,0,0,0} in an array let say data1 now i am having problem in reversing the values of data1 and when reversed calling myfunction because now i have stored values in data1 and my function has argument data so when i call myfunction it will call data not data1. please help me in this regard how can i resolve this issue i am much confused. @BLUEPIXY – user3863496 Jul 31 '14 at 06:33
  • @user3863496 Names will only different. – BLUEPIXY Jul 31 '14 at 10:05