tags:

views:

1676

answers:

7

Hello, I'm reading some code in the Ogre3D implementation, and I can't understand what does a void*-typed variable could mean. What does a pointer to void means in C++?

+2  A: 

It's a raw pointer to a spot in memory. It doesn't allow any pointer arithmetic like char * or int *.

Here's some examples of usage

http://theory.uwinnipeg.ca/programming/node87.html

Otávio Décio
+3  A: 

It's just a generic pointer, used to pass data when you don't know the type. You have to cast it to the correct type in order to use it.

Chuck
+2  A: 

It's a pointer to anything -- just a chunk of memory that you can play with -- might be an object, might be a char. You have to cast to do anything useful with it.

Rowland Shaw
+25  A: 

A pointer to void, void* can point to any object:

int a = 5;
void *p = &a;

double b = 3.14;
p = &b;

You can't dereference, increment or decrement that pointer, because you don't know what type you point to. The idea is that void* can be used for functions like memcpy that just copy memory blocks around, and don't care about the type that they copy.

Johannes Schaub - litb
waw - I didn't realize you couldn't increment a void* ! thanks!
xtofl
Quite a few compilers will let you - they assume that all pointer types are 32bit. This is wrong but common on Windows where people assume a 32bit x86.
Martin Beckett
@mgb: Never ever seen such a compiler.
dalle
I saw one that treated it like char* for arithmatic, which makes sense when you think about it.
Joshua
i don't think it makes sense. why should p++; increment it by one? could aswell increment by the pagesize or some other value. since sizeof(*p) is Big Fail, i'm lost at seeing how it could ever make sense :)
Johannes Schaub - litb
example compiler: gcc allows void pointer arithmetic and treats it like char*. Such code is nonportable, but possible in GNU-land.
Michael E
See http://gcc.gnu.org/onlinedocs/gcc-4.1.2/gcc/Pointer-Arith.html
DevSolar
A: 

Building off my prior posting...


ATTENTION: All memory addresses here are fictional. I'm just making them up to illustrate a point.


Given:

int data[] = {10,11,12};

We now have:

0xffff0000-0xffff0003  with a value of (int)(10)
0xffff0004-0xffff0007  with a value of (int)(11)
0xffff0008-0xffff000b  with a value of (int)(12)

(I'm not going to get into big-endian vs little-endian byte ordering here.)

If we have:

int * p = data;

We now have another memory location somewhere else, say:

 0xaaaa0000-0xaaaa0003  with a value of (int*)0xffff0000

We can use p[1] [or *(p + 1)] to refer to *(int*)(0xffff0004) [=11] as sizeof(int)=4 and 0xffff0000+sizeof(int) = 0xffff0004.

If we have:

void * v = data;

We now have another memory location somewhere else, say:

 0xbbbb0000-0xbbbb0003  with a value of (void*)0xffff0000.

However, void doesn't have any associated sizeof() information. We can't increment or decrement the pointer. We can't dereference to access the data stored in 0xffff0000. We can only utilize the value as a raw memory address.

If we want to use the data stored in (void*)0xffff0000, we first need to cast it to an appropriate type.

That said, (void *) is still quite useful as a means of passing addresses to arbitrary data structures around. For instance, memset(). It doesn't matter whether I'm zero'ing out a struct tm or a struct sockaddr. We just need a pointer to the struct and its size.

(This should go without saying, but... Beware using memset to zero out a class instance and, in doing so, overwriting the virtual pointer table.)

Mr.Ree
+1  A: 

A void pointer cannot point to a class member in C++.

kal
That's right, they're different sized pointers.
Joshua
i think that is because member pointers are completely different structured. If you want, then you can say they live in another address space (and then the reason is the same as the reason you cannot point to a function using `void*`). For sizes, a data member pointer on GCC (following the Itanium ABI) will have the size of a `ptrdiff_t` - it equals the size of an `int*` on my PC - the address space is the offset from the start of the object to its last member offset. For pointers to member functions, the size is usually bigger, in addition, of course.
Johannes Schaub - litb
A: 

I'm waking up this thread because I have a similar problem. I have a very large application A. Sometimes it needs to use a little application B. B instantiates an external dll I didn't write, we can call it G. B uses DllExport to export some functions I can call. Whenever I call B it makes a new G and deletes it again.

Now they changed the rules. I can only have one G. Easy, I think. Add an Init function to B's external interface, call it to instantiate my single instance of G. Return a void* to B, so whenever I want to call it it reuses the instance of B and thus of G. A is not allowed to know what happens in B, so the void* is perfect. I keep void* mB as a member of A.

B has some internal classes, we can call one ClassM. So B contains a member ClassM mM. When I hop into B it runs for a while until it tries to call mM.function in B. Then I get a buffer overrun.

So I googled and found your post. "A void pointer cannot point to a class member in C++." Is my void pointer to B losing its internal objects along the way? Where can I find out more? Am I doing this in the wrong way?

This is C++ in Visual Studio 2008. I use void* in other places to access Ada functions in the same way.

void * isn't perfect. B * would be perfect.
DevSolar