Problem on using a casted void pointer

K

kkirtac

Hi, i have a void pointer and i cast it to an appropriate known type
before using. The types which i cast this void* to are, from the
Intel's open source computer vision library. Here is my piece of non-
working code:

CvMat *rowVect = cvCreateMat(1,nfeatures,CV_MAKETYPE(images[0]-
depth,1));
//rowVect is a pointer to CvMat type

cvReshape( images[0], rowVect, 0, 1 ); //vectorize the image; readrow
is a 1xN matrix(vector)

void* ptr;

switch (images[0]->depth)
{
case IPL_DEPTH_8U :
ptr = (unsigned char *) rowVect->data.ptr ; //ptr is defined as an
unsigned char pointer
break; //
data is 'union' type

case IPL_DEPTH_8S :
ptr = (signed char *) rowVect->data.ptr ;
break;

case IPL_DEPTH_16S :
ptr = (unsigned short *) rowVect->data.ptr ;
break;

case IPL_DEPTH_32S :
ptr = (int *) rowVect->data.i ; // i is defined as an int pointer
break;

case IPL_DEPTH _32F :
ptr = (float *) rowVect->data.fl ; // fl is defined as float
pointer
break;

case IPL_DEPTH_64F :
ptr = (double *) rowVect->data.db ; // db is a double
break;

}

int i=0, k;
while(i<nsamples)
{
cvReshape( images, readrow, 0, 1 );
for(k=0; k<nfeatures; k++)
Data->data.db[i*(Data->width)+k] = (double) ptr[k]; // errors occur
here
//fill the Data matrix
i++;
}

Error : 1) 'void*' : unknown size
2) 'typecast' : cannot convert from void to double

i m sorry if it is illegal to point a 3rd party library here, but it
has also been written in standard C. But my problem is a pure "C
language" problem i think. I cast a void pointer but then i cant use
it...

Regards
 
B

borophyll

Hi, i have a void pointer and i cast it to an appropriate known type
before using. The types which i cast this void* to are, from the
Intel's open source computer vision library. Here is my piece of non-
working code:

CvMat *rowVect = cvCreateMat(1,nfeatures,CV_MAKETYPE(images[0]->depth,1));

//rowVect is a pointer to CvMat type

cvReshape( images[0], rowVect, 0, 1 ); //vectorize the image; readrow
is a 1xN matrix(vector)

void* ptr;

switch (images[0]->depth)
{
case IPL_DEPTH_8U :
ptr = (unsigned char *) rowVect->data.ptr ; //ptr is defined as an
unsigned char pointer
break; //
data is 'union' type

case IPL_DEPTH_8S :
ptr = (signed char *) rowVect->data.ptr ;
break;

case IPL_DEPTH_16S :
ptr = (unsigned short *) rowVect->data.ptr ;
break;

case IPL_DEPTH_32S :
ptr = (int *) rowVect->data.i ; // i is defined as an int pointer
break;

case IPL_DEPTH _32F :
ptr = (float *) rowVect->data.fl ; // fl is defined as float
pointer
break;

case IPL_DEPTH_64F :
ptr = (double *) rowVect->data.db ; // db is a double
break;

}

int i=0, k;
while(i<nsamples)
{
cvReshape( images, readrow, 0, 1 );
for(k=0; k<nfeatures; k++)
Data->data.db[i*(Data->width)+k] = (double) ptr[k]; // errors occur
here
//fill the Data matrix
i++;
}

Error : 1) 'void*' : unknown size
2) 'typecast' : cannot convert from void to double

i m sorry if it is illegal to point a 3rd party library here, but it
has also been written in standard C. But my problem is a pure "C
language" problem i think. I cast a void pointer but then i cant use
it...

Regards




Try rewriting (double) ptr[k] as ((double *)ptr)[k]

Regards,
B.
 
K

kkirtac

Hi, i have a void pointer and i cast it to an appropriate known type
before using. The types which i cast this void* to are, from the
Intel's open source computer vision library. Here is my piece of non-
working code:
CvMat *rowVect = cvCreateMat(1,nfeatures,CV_MAKETYPE(images[0]->depth,1));
//rowVect is a pointer to CvMat type
cvReshape( images[0], rowVect, 0, 1 ); //vectorize the image; readrow
is a 1xN matrix(vector)
void* ptr;
switch (images[0]->depth)
{
case IPL_DEPTH_8U :
ptr = (unsigned char *) rowVect->data.ptr ; //ptr is defined as an
unsigned char pointer
break; //
data is 'union' type
case IPL_DEPTH_8S :
ptr = (signed char *) rowVect->data.ptr ;
break;
case IPL_DEPTH_16S :
ptr = (unsigned short *) rowVect->data.ptr ;
break;
case IPL_DEPTH_32S :
ptr = (int *) rowVect->data.i ; // i is defined as an int pointer
break;
case IPL_DEPTH _32F :
ptr = (float *) rowVect->data.fl ; // fl is defined as float
pointer
break;
case IPL_DEPTH_64F :
ptr = (double *) rowVect->data.db ; // db is a double
break;

int i=0, k;
while(i<nsamples)
{
cvReshape( images, readrow, 0, 1 );
for(k=0; k<nfeatures; k++)
Data->data.db[i*(Data->width)+k] = (double) ptr[k]; // errors occur
here
//fill the Data matrix
i++;
}

Error : 1) 'void*' : unknown size
2) 'typecast' : cannot convert from void to double
i m sorry if it is illegal to point a 3rd party library here, but it
has also been written in standard C. But my problem is a pure "C
language" problem i think. I cast a void pointer but then i cant use
it...

Try rewriting (double) ptr[k] as ((double *)ptr)[k]

Regards,
B.


Hmm thank you but the problem here is, if we set a double* in front of
ptr, then it reads amount of bytes that corresponds to type 'double'.
What i want to do here is to decide the amount of bytes(the type that
will come in front of 'ptr') in the upper 'switch-case' statement
once, and read that amount of bytes in each iteration, cast it to
double type. For instance, if the switch-case decides that ptr will be
an unsigned char* , then instead of the double* in the while loop, i
want unsigned char* be placed there, and then convert the result to
double like this : (double)((unsigned char *)ptr)[k] . But problem is
i want this to happen automatically..that i dont want to run the
switch-case inside the while loop to decide for that..I m sorry if it
got too complicated..
Regards
 
I

Ian Collins

kkirtac said:
Hmm thank you but the problem here is, if we set a double* in front of
ptr, then it reads amount of bytes that corresponds to type 'double'.
What i want to do here is to decide the amount of bytes(the type that
will come in front of 'ptr') in the upper 'switch-case' statement
once, and read that amount of bytes in each iteration, cast it to
double type. For instance, if the switch-case decides that ptr will be
an unsigned char* , then instead of the double* in the while loop, i
want unsigned char* be placed there, and then convert the result to
double like this : (double)((unsigned char *)ptr)[k] .

That doesn't make sense, if ptr is unsigned char*, ptr[k+1] will be one
byte on from ptr[k], so it makes no sense and is potentially crash
inducing to cast these arbitrary byte sequence to double.
 
K

kkirtac

kkirtac said:
Hmm thank you but the problem here is, if we set a double* in front of
ptr, then it reads amount of bytes that corresponds to type 'double'.
What i want to do here is to decide the amount of bytes(the type that
will come in front of 'ptr') in the upper 'switch-case' statement
once, and read that amount of bytes in each iteration, cast it to
double type. For instance, if the switch-case decides that ptr will be
an unsigned char* , then instead of the double* in the while loop, i
want unsigned char* be placed there, and then convert the result to
double like this : (double)((unsigned char *)ptr)[k] .

That doesn't make sense, if ptr is unsigned char*, ptr[k+1] will be one
byte on from ptr[k], so it makes no sense and is potentially crash
inducing to cast these arbitrary byte sequence to double.

hmm it just turns 47 to 47.0000000 ..nothing more than that , but my
prob. is not that..
 
I

Ian Collins

kkirtac said:
kkirtac said:
Hmm thank you but the problem here is, if we set a double* in front of
ptr, then it reads amount of bytes that corresponds to type 'double'.
What i want to do here is to decide the amount of bytes(the type that
will come in front of 'ptr') in the upper 'switch-case' statement
once, and read that amount of bytes in each iteration, cast it to
double type. For instance, if the switch-case decides that ptr will be
an unsigned char* , then instead of the double* in the while loop, i
want unsigned char* be placed there, and then convert the result to
double like this : (double)((unsigned char *)ptr)[k] .
That doesn't make sense, if ptr is unsigned char*, ptr[k+1] will be one
byte on from ptr[k], so it makes no sense and is potentially crash
inducing to cast these arbitrary byte sequence to double.

hmm it just turns 47 to 47.0000000 ..nothing more than that , but my
prob. is not that..
Ah, sorry, I misread your parenthesis (common problem with yucky code!).
In that case, the cast is unnecessary.

The casts in you original are also unnecessary.

Your best bet is to put the switch in a function and call that from the
loop.
 
C

CBFalconer

kkirtac said:
Hi, i have a void pointer and i cast it to an appropriate known
type before using. The types which i cast this void* to are, from
the Intel's open source computer vision library. Here is my piece
of non-working code:
.... snip ...

void* ptr;
.... snip ...

case IPL_DEPTH_8S: ptr = (signed char *) rowVect->data.ptr;
break;
.... snip ...

Error : 1) 'void*' : unknown size
2) 'typecast' : cannot convert from void to double

Don't cast there. You are placing the result of the cast in a
void*, which immediately casts it right back to a void*, which
can't be dereferenced, etc.
 
K

Keith Thompson

CBFalconer said:
Don't cast there. You are placing the result of the cast in a
void*, which immediately casts it right back to a void*, which
can't be dereferenced, etc.

No, it's immediately *converted* back to void*. A cast is an explicit
operator; there's no such thing as an implicit cast.
 
B

Barry Schwarz

Hi, i have a void pointer and i cast it to an appropriate known type
before using.

Unfortunately, that is not what you have. What you have is a void
pointer to which you assign a cast-ed value, thereby losing any
information the cast might have provided.
The types which i cast this void* to are, from the
Intel's open source computer vision library. Here is my piece of non-
working code:

CvMat *rowVect = cvCreateMat(1,nfeatures,CV_MAKETYPE(images[0]->depth,1));


//rowVect is a pointer to CvMat type

cvReshape( images[0], rowVect, 0, 1 ); //vectorize the image; readrow
is a 1xN matrix(vector)

There is no readrow. The major, perhaps only, benefit of comments is
help someone reading the code understand what is happening. Incorrect
or misleading comments perform the opposite function.

If anyone is tempted to try to compile your code, your use of // style
comments makes it impractical. Line wrap is a fact of life in Usenet.
Use /* */ style comments and eliminate syntax errors introduced by
message readers.
void* ptr;


switch (images[0]->depth)
{
case IPL_DEPTH_8U :
ptr = (unsigned char *) rowVect->data.ptr ; //ptr is defined as an
unsigned char pointer

Nothing you do on the right hand side will change the definition of
ptr. It is still a pointer to void. Perhaps you meant data.ptr. If
so, then the cast is particularly useless (as opposed to generally
useless) since you do not change the type of the expression. See next
comment.
break; // data is 'union' type


case IPL_DEPTH_8S :
ptr = (signed char *) rowVect->data.ptr ;

There is an implicit conversion defined between object pointers and
pointers to void. It is never necessary to cast one to the other on a
simple assignment.
break;


case IPL_DEPTH_16S :
ptr = (unsigned short *) rowVect->data.ptr ;
break;


case IPL_DEPTH_32S :
ptr = (int *) rowVect->data.i ; // i is defined as an int pointer
break;


case IPL_DEPTH _32F :
ptr = (float *) rowVect->data.fl ; // fl is defined as float
pointer
break;


case IPL_DEPTH_64F :
ptr = (double *) rowVect->data.db ; // db is a double

Now you introduce confusion. Every other assignment to ptr was from a
pointer. Are you really trying to stuff the VALUE of a double into a
void*. (I hope not. There is no guarantee it will fit. This is also
no guarantee that such a conversion is defined). Perhaps you meant
the comment to day "db is a double pointer" which would be consistent
with your previous code and your for loop below.

At this point, ptr contains the address obtained from one of the
pointers in the data union. While you were going through the switch,
you actually determined what type of data you want to deal with.
However, now all you have is a void* that points to something but you
no longer know what that something is.
int i=0, k;
while(i<nsamples)
{
cvReshape( images, readrow, 0, 1 );
for(k=0; k<nfeatures; k++)
Data->data.db[i*(Data->width)+k] = (double) ptr[k]; // errors occur
here


ptr is a pointer to void. If it were a valid expression, ptr[k] would
be the k'th void ptr pointed to. However, void is a permanently
incomplete type (it can never be completed). As such, an expression
of type void is not an arithmetic value that can be converted to
double.

While you compiler will have no trouble distinguishing between Data
and data, I don't think most people who would be tempted to help will
appreciate the distinction.
//fill the Data matrix
i++;
}


Error : 1) 'void*' : unknown size
2) 'typecast' : cannot convert from void to double


i m sorry if it is illegal to point a 3rd party library here, but it
has also been written in standard C. But my problem is a pure "C
language" problem i think. I cast a void pointer but then i cant use
it...

The only place where you know the type of data that ptr points to is
inside each switch case. That would be the logical place to process
the data. Furthermore, it would make life so much simpler to use the
"original" pointers (i, fl, etc) rather than try to use ptr for
everything. For example

case IPL_DEPTH_32S :
{
int i=0, k;
while(i<nsamples)
{
cvReshape( images, readrow, 0, 1 );
for(k=0; k<nfeatures; k++)
Data->data.db[i*(Data->width)+k] = rowVect->data.i[k];
/* Since I don't know anything about your structures, unions, or
non-standard functions, I don't vouch for the validity of any of the
expressions. I am only translating your code to work within the case.
*/
i++;
}
}

With the exception of the expression data.i, this same code would be
used for all cases. That would make this a candidate for a macro.


Remove del for email
 
K

kkirtac

Hi, i have a void pointer and i cast it to an appropriate known type
before using.

Unfortunately, that is not what you have. What you have is a void
pointer to which you assign a cast-ed value, thereby losing any
information the cast might have provided.
The types which i cast this void* to are, from the
Intel's open source computer vision library. Here is my piece of non-
working code:
CvMat *rowVect = cvCreateMat(1,nfeatures,CV_MAKETYPE(images[0]->depth,1));
//rowVect is a pointer to CvMat type
cvReshape( images[0], rowVect, 0, 1 ); //vectorize the image; readrow
is a 1xN matrix(vector)

There is no readrow. The major, perhaps only, benefit of comments is
help someone reading the code understand what is happening. Incorrect
or misleading comments perform the opposite function.

If anyone is tempted to try to compile your code, your use of // style
comments makes it impractical. Line wrap is a fact of life in Usenet.
Use /* */ style comments and eliminate syntax errors introduced by
message readers.


void* ptr;
switch (images[0]->depth)
{
case IPL_DEPTH_8U :
ptr = (unsigned char *) rowVect->data.ptr ; //ptr is defined as an
unsigned char pointer

Nothing you do on the right hand side will change the definition of
ptr. It is still a pointer to void. Perhaps you meant data.ptr. If
so, then the cast is particularly useless (as opposed to generally
useless) since you do not change the type of the expression. See next
comment.
break; // data is 'union' type
case IPL_DEPTH_8S :
ptr = (signed char *) rowVect->data.ptr ;

There is an implicit conversion defined between object pointers and
pointers to void. It is never necessary to cast one to the other on a
simple assignment.


case IPL_DEPTH_16S :
ptr = (unsigned short *) rowVect->data.ptr ;
break;
case IPL_DEPTH_32S :
ptr = (int *) rowVect->data.i ; // i is defined as an int pointer
break;
case IPL_DEPTH _32F :
ptr = (float *) rowVect->data.fl ; // fl is defined as float
pointer
break;
case IPL_DEPTH_64F :
ptr = (double *) rowVect->data.db ; // db is a double

Now you introduce confusion. Every other assignment to ptr was from a
pointer. Are you really trying to stuff the VALUE of a double into a
void*. (I hope not. There is no guarantee it will fit. This is also
no guarantee that such a conversion is defined). Perhaps you meant
the comment to day "db is a double pointer" which would be consistent
with your previous code and your for loop below.

At this point, ptr contains the address obtained from one of the
pointers in the data union. While you were going through the switch,
you actually determined what type of data you want to deal with.
However, now all you have is a void* that points to something but you
no longer know what that something is.


int i=0, k;
while(i<nsamples)
{
cvReshape( images, readrow, 0, 1 );
for(k=0; k<nfeatures; k++)
Data->data.db[i*(Data->width)+k] = (double) ptr[k]; // errors occur
here


ptr is a pointer to void. If it were a valid expression, ptr[k] would
be the k'th void ptr pointed to. However, void is a permanently
incomplete type (it can never be completed). As such, an expression
of type void is not an arithmetic value that can be converted to
double.

While you compiler will have no trouble distinguishing between Data
and data, I don't think most people who would be tempted to help will
appreciate the distinction.
//fill the Data matrix
i++;
}
Error : 1) 'void*' : unknown size
2) 'typecast' : cannot convert from void to double
i m sorry if it is illegal to point a 3rd party library here, but it
has also been written in standard C. But my problem is a pure "C
language" problem i think. I cast a void pointer but then i cant use
it...

The only place where you know the type of data that ptr points to is
inside each switch case. That would be the logical place to process
the data. Furthermore, it would make life so much simpler to use the
"original" pointers (i, fl, etc) rather than try to use ptr for
everything. For example

case IPL_DEPTH_32S :
{
int i=0, k;
while(i<nsamples)
{
cvReshape( images, readrow, 0, 1 );
for(k=0; k<nfeatures; k++)
Data->data.db[i*(Data->width)+k] = rowVect->data.i[k];
/* Since I don't know anything about your structures, unions, or
non-standard functions, I don't vouch for the validity of any of the
expressions. I am only translating your code to work within the case.
*/
i++;
}
}

With the exception of the expression data.i, this same code would be
used for all cases. That would make this a candidate for a macro.

Remove del for email


Thank you, embedding the loop into "switch-case"s looks the best way..
Regards
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,480
Members
44,900
Latest member
Nell636132

Latest Threads

Top