what is the use of void pointer?

V

Viv

You should use it when you do not know what data type the memory
contains. The advantage is that once u know the data type, u may
typecast the void ptr into the appropriate data type.
 
S

Sandeep

Viv said:
You should use it when you do not know what data type the memory
contains. The advantage is that once u know the data type, u may
typecast the void ptr into the appropriate data type.

A good example is the "malloc" function. It returns a void* and you can
typecast it to whatever type you need.

Prototype : void *malloc(size_t size);
Usage : int *n = (int *) malloc(sizeof(int));
 
F

Flash Gordon

Sandeep said:
A good example is the "malloc" function. It returns a void* and you can
typecast it to whatever type you need.

Prototype : void *malloc(size_t size);
Usage : int *n = (int *) malloc(sizeof(int));

That is terrible usage of malloc, and I'm sure you have been here long
enough to have seen the generally recommended usage of

int *n = malloc(sizeof *n);

You don't need to cast the return value of malloc, and doing so can
prevent the compiler from warning you about not having a declaration of
malloc in scope. Also, the form you showed means having to get the type
correct three times instead of once, having to check it in three places,
and having to change it in three places instead of one if it needs changing.
 
S

Sandeep

That is terrible usage of malloc, and I'm sure you have been here long
enough to have seen the generally recommended usage of

int *n = malloc(sizeof *n);

You don't need to cast the return value of malloc, and doing so can
prevent the compiler from warning you about not having a declaration of
malloc in scope. Also, the form you showed means having to get the type
correct three times instead of once, having to check it in three places,
and having to change it in three places instead of one if it needs changing.

I was trying to explain the use of "void *" and though that to a newbie
it would have been easier to understand it as
int *n = (int *)malloc(sizeof(int));

But Point Taken, I should not explain one concept in a way that gives a
not so correct information about some other concept.
 
P

pete

Sandeep wrote:
I was trying to explain the use of "void *"
and though that to a newbie
it would have been easier to understand it as
int *n = (int *)malloc(sizeof(int));

But Point Taken,
I should not explain one concept in a way that gives a
not so correct information about some other concept.

It's not some other concept.
The lack of cast
is the reason for the existence of the pointer to void type.
Previous to the invention of the pointer to void type,
the pointer to char type was used to accomplish the same tasks.
 
P

pete

pete said:
It's not some other concept.
The lack of cast
is the reason for the existence of the pointer to void type.

"use" is a better word to use there, than "existence".
It's existence follows logically from the invention of
type void.
 
K

Keith Thompson

pete said:
It's not some other concept.
The lack of cast
is the reason for the existence of the pointer to void type.
Previous to the invention of the pointer to void type,
the pointer to char type was used to accomplish the same tasks.

I wouldn't say that the lack of a cast operator is the reason for the
existence of void*. void* is a generic pointer type. It needs to be
convertible to any pointer-to-object type, but the fact that it's
*implicitly* convertible is just a convenience. One can imagine a
C-like language in which void* is not implicitly convertible, but is
still useful (and one might imagine calling this hypothetical language
C++).
 
S

Sandeep

It's not some other concept.
The lack of cast
is the reason for the existence of the pointer to void type.
Previous to the invention of the pointer to void type,
the pointer to char type was used to accomplish the same tasks.

K & R - Second Edition

Section 6.6

Char *strdup(char *s)
{
char *p;
p = ( char *) malloc(strlen(s) + 1) ;
......
}

K & R
Section 7.8.5
The pointer returned by malloc has the proper alignment for the object
in question, but it must be cast into the appropriate type.

PS : "void *" existed at the point this edition went into press.

Things might have changed a lot, but
int *p = (int *) malloc ( sizeof(int) ); , is NOT a SIN.

- Sandeep
 
M

Mark McIntyre

K & R - Second Edition

Read the errata.
p = ( char *) malloc(strlen(s) + 1) ;

which specifically mentions that the cast was a mistake...
K & R
Section 7.8.5
The pointer returned by malloc has the proper alignment for the object
in question, but it must be cast into the appropriate type.

same point.
Things might have changed a lot, but
int *p = (int *) malloc ( sizeof(int) ); , is NOT a SIN.

Ben Pfaff has I believe a useful page all about hte sinfulness of
casting the return from malloc.
 
P

pete

"use" is the correct word, rather than "existence".
K & R - Second Edition
PS : "void *" existed at the point this edition went into press.

K & R First Edition is older than void.

Chapter 8, Section 8.7

free(ap) /* put block ap in free list */
char *ap;
{

....
 
R

Richard Heathfield

(Before we get into the meat of this subject, I'd just like to agree with a
number of people who have pointed out that casting a void pointer is almost
always utterly pointless. There, done that - now, on with the show...)

nick said:
i do not know what is the use of (e.g. void *pt), when will use it.

A void pointer is useful when you are writing code which does not know the
type of the data being presented to it, but which can do one of (at least)
two things:

(a) assume a particular representation;
(b) pass the data to a function that /does/ know the type.

Here is an example of the first of those:

void *memcpy(void *dest, const void *src, size_t len)
{
unsigned char *d = dest;
const unsigned char *s = src;
while(len--)
{
*d++ = *s++;
}
return dest;
}

(In practice, memcpy would probably be implemented much more cleverly than
this - but the above would work just fine.) Because memcpy's job is simply
to copy data from one place to another, it can legitimately treat src as a
mere sequence of bytes.

Here is an example of the second item in my list, where we don't process the
data at all, but simply pass it on to a function whose address the caller
gives us.

#include <stdio.h>

void iterate(void *p,
size_t size,
size_t num,
void (*iterfunc)(void *, void *),
void *args)
{
size_t i;
unsigned char *e = p;
for(i = 0; i < num; i++)
{
(*iterfunc)(e + i * size, args);
}
}

void foreachint(void *vpi, void *vfp)
{
int *pi = vpi;
FILE *fp = vfp;
fprintf(fp, " %d", *pi);
}

void foreachdouble(void *vpd, void *vfp)
{
double *pd = vpd;
FILE *fp = vfp;
fprintf(fp, " %f", *pd);
}

int main(void)
{
int foo[] = { 3, 1, 4, 1, 5, 9, 2, 6 };
double bar[] = { 0.1, 0.2, 0.3 };
iterate(foo,
sizeof foo[0],
sizeof foo / sizeof foo[0],
foreachint,
stdout);
putchar('\n');
iterate(bar,
sizeof bar[0],
sizeof bar / sizeof bar[0],
foreachdouble,
stdout);
putchar('\n');
return 0;
}

In case you hadn't already guessed, the output of this program is:

3 1 4 1 5 9 2 6
0.100000 0.200000 0.300000

There are better ways to handle abstract data in C, but this is a reasonably
good way to ease yourself gently into the concept.
 
J

Jack Klein

You should use it when you do not know what data type the memory
contains. The advantage is that once u know the data type, u may
typecast the void ptr into the appropriate data type.

Why are you talking to 'u'? He hasn't read this group in years!

Then there is the fact that your answer needs something to be desired.
You don't need to cast a void pointer to a pointer to any type of
object, and while you can cast a void pointer to some non-pointer data
types, namely integer types, it is usually not a good idea.
 
P

Peter Nilsson

Mark said:
Read the errata.


which specifically mentions that the cast was a mistake...

Your interpretation of "The example is correct and works"
is different to mine!

Here's the relevant errata...

"142(§6.5, toward the end): The remark about casting the
return value of malloc ("the proper method is to declare...
then explicitly coerce") needs to be rewritten. The example
is correct and works, but the advice is debatable in the
context of the 1988-1989 ANSI/ISO standards. 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 *. The explicit
cast can cover up an unintended error. On the other hand,
pre-ANSI, the cast was necessary, and it is in C++ also."

It says that the _remark_ needs to be rewritten as the advice is
debatable. That is not the same as saying the cast was a mistake.

The Preface to K&R2 states they used a C++ compiler to originally
test sample code. In the absence of any other commentary from the
authors, I can easily imagine that the code would remain the same,
however the remark would be changed to say that the cast is not
required.

Ben Pfaff has I believe a useful page all about hte sinfulness of
casting the return from malloc.

You mean...?

http://benpfaff.org/writings/clc/malloc-cast.html.

At least Ben had the good sense to acknowledge that some
(respectable) C programmers disagree...

"I agree that you have to write more casts in C++ than in C,
and I agree that casts can sometimes disguise other problems.
But it's been my experience over the past ten years that casts
tend to hide stupid bugs, which are relatively easy to find,
while compiling as C++ tends to find subtler bugs, which are
not. The tradeoff has been well worth it for us."

- P.J. Plauger
 
A

aakash.joshi

Hi all,

Apart frm all that healthy discussion abt void ptrs, i would like to
add one more usage of void ptrs.

void ptrs can be used to create NULL pointers. A constant 0 or any
expression resulting in 0, when casted into (void*) is known as a NULL
ptr. such a NULL ptr can be used for comparing pointers. it will always
be unequal when compared to a legal pointer value.

its a good programming practice in comparing pointers like this

thanx
 
P

pete

A constant 0 or any expression resulting in 0,
when casted into (void*) is known as a NULL ptr.

Not exactly.
NULL, is a macro which expands to a null pointer constant.

Any constant expression
with an integer type that compares equal to zero,
is already a null pointer constant,
with or without the (void *) cast.

When you write "NULL pointer"
nobody knows whether you mean
1 the NULL macro
2 a null pointer constant
3 a null pointer

A null pointer,
is any pointer of any type
that compares equal to a null pointer constant.
 
P

pete

pete said:
Not exactly.
NULL, is a macro which expands to a null pointer constant.

Any constant expression
with an integer type that compares equal to zero,
is already a null pointer constant,
with or without the (void *) cast.

When you write "NULL pointer"
nobody knows whether you mean
1 the NULL macro
2 a null pointer constant
3 a null pointer

Actually,
those are what I would have assumed that you might have meant,
if you hadn't already defined "NULL pointer" as term,
meaning something that you just made up.
 
Z

Zoran Cutura

Viv said:
You should use it when you do not know what data type the memory
contains. The advantage is that once u know the data type, u may
typecast the void ptr into the appropriate data type.

Actually the advantage is, that you don't have to type cast that void
pointer, but can assign it directly to some pointer of the designated
type.
 

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,763
Messages
2,569,562
Members
45,039
Latest member
CasimiraVa

Latest Threads

Top