When to use void pointer?

I understand the use of the void pointer to implement malloc.

void* malloc ( size_t size ); 

Can someone suggest other reasons or provide some scenarios where this is useful in practice.

thank

+31
c ++ c pointers
Jun 22 '09 at 5:31
source share
13 answers

One good void* script is used when you want to implement any common ADT, if you just don't know what type of data it will store and solve. For example, a linked list is as follows:

 typedef struct node_t node; struct { void* data; node* prev, next; } node_t; typedef struct list_t list; typedef void* (func)(void*) cpy_func; typedef void (func)(void*) del_func; struct { node* head, tail, curr; cpy_func copy; del_func delete; } list_t; initializeLinkedList(cpy_func cpy, del_func del); //here you keep going defining an API 

Here, for example, you pass initialization function pointers to other functions that will be able to copy your data type to your list and release it later. Therefore, using void* , you make your list more general.

I think void* stayed in C ++ only because of backward compatibility, since in C ++ you have more secure and sophisticated ways to achieve the same result as patterns, functors, etc., and you don't need use malloc while c ++ programming.

As for C ++, I have no specific useful examples.

+29
Jun 22 '09 at 6:19 06:19
source share

If you interact with C code and must pass through a C ++ object, but the C library will only accept a generic pointer, then when you retrieve the pointer, you need to convert it to the appropriate type.

Void pointers probably shouldn't be used very often, but they can help when you try to use a library function that works with arbitrary pointers, and no matter what data is represented by this memory.

+11
Jun 22 '09 at 5:40
source share

void pointers should be used at any time when the contents of the data block are irrelevant. For example, when copying data, the contents of the memory area are copied, but the data format is not important.

For functions running on memory blocks without the need to understand the contents with void pointers, the design is explained to users so that they know that the function does not care about any data format. Often functions are encoded to take char * to process blocks of memory when the function is actually agnostic.

+8
Jun 22 '09 at 5:55
source share

In C ++, I found the most convincing use case for void * pointers to provide code for storing arbitrary "user data" on an object that they already use.

Let's say you wrote a class representing Car for use in software that does useful things with Car objects (simulating traffic, car rental inventory, whatever). Now say that you are in a situation where your application wants to track arbitrary contents of a Car trunk. Details of what is stored in the trunk are not important for the Car class and can be any - it really depends on the purpose of the application using the Car class. Enter the void * pointer.

 class Car { public: // Existing methods of your Car class void setContentsOfTrunk(void* contentsOfTrunk); void* contentsOfTrunk() const; private: void* m_contentsOfTrunk; } 

Now, any application using the Car class has the ability to attach an arbitrary data object to an existing Car object so that it can be obtained from any code that has a Car object. The contents of the body "move" with the Car object, wherever it is in your code.

In this case, there are two uses for void *.

The first is your class template, based on the content type of the contents of the trunk:

 template <class TrunkContentsType> class Car { public: // Existing methods of your Car class void setContentsOfTrunk(TrunkContentsType contentsOfTrunk); TrunkContentsType contentsOfTrunk() const; private: TrunkContentsType m_contentsOfTrunk; } 

It seems overly invasive. The type of trunk contents is important only for the application. Algorithms and data structures that work with Car objects do not care about what's in the trunk. By clabbling a class, you force applications, using the class, to choose the type of trunk content, but in many cases, applications also do not care about the contents of the trunk.

The second alternative is to derive a new class from Car, which adds a data member and accessors for the contents of the trunks:

 class Car { public: // Existing methods of your Car class // No methods having anything to do with trunk contents. private: // No data member representing trunk contents. } class CarWithTrunkContents { public: // Existing methods of your Car class void setContentsOfTrunk(TrunkContentsType contentsOfTrunk); TrunkContentsType contentsOfTrunk() const; private: TrunkContentsType m_contentsOfTrunk; } 

The new CarWithTrunkContents class is an application-specific class that adds a data member of the type in which the application must store the contents of the trunk on the car. It also seems unnecessarily heavy. Why should you get a whole new class to add an extra piece of data that doesn't affect class behavior? And if it is common enough for applications using the Car class to store the contents of trunks, why make each application output a new class for its specific type of trunk content?

Finally, although my far-fetched example of the contents of a connector line can paint a vivid picture of arbitrary contents of a connector line moving with a Car object, in practice, you are likely to provide an even more general mechanism for linking application-specific data to a Car :

 class Car { public: // Existing methods of your Car class void setUserData(void* userData); void* userData() const; private: void* m_userData; } 

Thus, the application can attach an object representing the contents of the trunk, or an object representing the license and registration of the driver, or an object representing the lease, or something else. I saw a void * pointer called userData (that is, understood by the user of the class), "blindData" (ie the class is blind to the contents of the object that it carries), or "applicationData" (i.e. data of type and goals defined by the application).

+6
Sep 11 '15 at 15:34
source share

Another example of such C "generics" implemented with void * is the standard qsort function:

 void qsort(void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *)); 

You can sort an array of any type: int, long, double, char * or some pointers to a structure ...

+3
Jun 22 '09 at 7:38
source share

A BIG way to learn all about void * and other C topics is to watch the first half of Stanford's fantastic Programming Paradigms on iTunes-U. This really explains void * (C generics) and pointers are generally fantastic! It definitely helped me get to know C ...

One of the biggest uses is to use void * if you want to be able to accept different types of data into functions. (heres example: http://142.132.30.225/programming/node87.html )

Here is another example of what you can use for:

  int i; char c; void *the_data; i = 6; c = 'a'; the_data = &i; printf("the_data points to the integer value %d\n", *(int*) the_data); the_data = &c; printf("the_data now points to the character %c\n", *(char*) the_data); 

If you don't want to watch the free stanford classes, I would recommend the void googling pointer and read all the stuff there.

+2
Jun 22 '09 at 5:41
source share

It is usually used in numeric code, for example, the C root solver function might look like this:

 double find_root(double x0, double (*f)(double, void*), void* params) { /* stuff */ y = f(x, params); /* other stuff */ } 

params dropped by f into some structure that he knows about, but find_root does not.

+2
Jun 22 '09 at 6:35
source share

Next to the C interface, I find that I use only void pointers when I need to debug / trace some code and how to know the address of a specific pointer.

 SomeClass * myInstance; // ... std::clog << std::hex << static_cast< void* >(myInstance) << std::endl; 

Will output something like

 0x42A8C410 

And, in my opinion, it documents well what I'm trying to do (know the address of the pointer, not anything about this instance)

+2
Jun 22 '09 at 7:55
source share

Void pointers are useful when you write code that should run on many operating systems and should be agnostic enough for the basic APIs.

For example, OS X, Windows, and Linux all have the basic concept of a window object, but they are all very different. So I have a generic code that passes them as void *, and then specific platform implementations that pass void * to their own type (HWND, etc.).

But, as others have said in this thread, this kind of thing should be avoided if necessary.

+1
Jun 22 '09 at 5:54
source share

Take a look at sqlite3_exec () . You run an SQL query and want to somehow process the results (store them in a container). You call sqlite3_exec () and pass the callback pointer and void * pointer to any object you want (including the container). When sqlite3_exec () is executed, it calls a callback for each row received and passes that void * pointer so that the callback can direct the pointer and do whatever you intended.

The important thing is that sqlite3_exec () does not care what the callback does and what pointer you pass. void * exactly for such pointers.

+1
Jun 22 '09 at 5:57
source share

void * really is C-ism and allows C to do some things that it could not reasonably have done otherwise.

char * cannot be used from any point of view, since different platforms can create different types of pointers. char * not necessarily treated the same (or the same size) as void * .

So, when the data type is not known in C (or is polymorphic or otherwise dynamic), then void * allows you to generate the correct base pointer type - one that can correctly indicate something.

In C ++, void * usually should never appear, except in the context of interacting with legacy C code in one form or another.

+1
Oct 26 '09 at 13:52
source share

There is a big advantage to using a void pointer. A pointer variable is a variable that stores the address of another variable. Example:

 int a; int *x= &a; 

Now 'x' stores the address of an integer variable.

But this fails:

 float f; int *x = &f; 

Because the Integer pointer variable can only store the address of an integer variable. in the same way, it applies to other data types.

When you use the void * pointer, it gives an edge to store the address of any TYPE variable.

 void *pointer = &i; void *pointer = &f; 

when removing it must be postponed.

 *((int*)pointer) 

So, carefully use the void pointer.

This may help you, thanks.

+1
Jul 14 '15 at 17:41
source share
 int (*f) (void); f =(void*) getprocaddress(dll,"myfunction"); 

to make the compiler happy

-3
Oct 26 '09 at 13:45
source share



All Articles