简体   繁体   English

C ++取消引用void指针,将int ptr转换为void ptr

[英]C++ dereference a void pointer , converting int ptr to void ptr

These lines of code show below error: 这些代码行显示如下错误:

int e = 5, * ePtr = &e;
void * vPtr = ePtr; 
cout << *vPtr; 

syntax error : 语法错误:

`void*' is not a pointer-to-object type `void *'不是指向对象的类型

I know: 我知道:

  1. any pointer type can be stored in void pointer type without explicit cast 任何指针类型都可以存储在void指针类型中而无需显式转换
  2. dereferencing attempt to void pointer is a syntax error 解除引用尝试void指针是语法错误

but if we can not do point # 2, what is the use of point # 1 except for being syntactically correct? 但如果我们不能做#2点,除了语法正确之外,点#1的用途是什么? I want to print 5 (ie e here) using vPtr ..is that possible? 我想用vPtr打印5(即e )这可能吗?

This works fine: 这很好用:

int e = 5, * ePtr = &e;
void * vPtr = ePtr; //specific to generic Ok!
double * dPtr = (double *)vPtr; //to let compiler know stoarge size
cout << *dPtr; //indirectly it is vPtr i.e. a void ptr, can be deref only if cast

To deference a void* pointer, you need to cast the pointer back to a compatible type. 要遵循void*指针,您需要将指针强制转换为兼容类型。

void* pointers are frequently used in C, however, since in C++ we can do function overloading and polymorphism, their use is much more limited. void*指针经常在C中使用,但是,因为在C ++中我们可以执行函数重载和多态,它们的使用更加有限。

A good exemple of use of void* pointers in C are functions that use callbacks : 在C中使用void*指针的一个很好的例子是使用回调的函数:

int pthread_create(pthread_t *thread, const pthread_attr_t *attr, 
                   void *(*start_routine) (void *), void *arg);

When you call the pthread_create function, it calls your start_routine back. 当你调用pthread_create函数时,它会调用你的start_routine In this case, you may want to pass some data to your start_routine . 在这种情况下,您可能希望将一些数据传递给start_routine Since the thread library cannot declare a pthread_create function for every type you may want to pass to you callback, the void* type is used instead. 由于线程库无法为您可能想要传递给回调的每种类型声明pthread_create函数,因此使用void*类型。

void myCallBack(void* arg) {
   int* value = (int*)arg;

   /* Do something with value: it is an int* now*/
   printf("Message from callback %d\n", *value);
}


/* Some main function or whatever... */
{ 
  /*  ... */
  int foo = 123;
  ret = pthread_create(&thread, &attr,myCallBack, &foo);

  /*  ... */
}

void* can point to anything, therefore assigning any pointer to it is perfectly fine. void*可以指向任何东西,因此为它指定任何指针都非常好。

But because it might point to anything, dereferencing it is not possible: The compiler does not know which object type it points to, so it is not able to generate code to do the right thing depending on the object's type. 但是因为它可能指向任何东西,所以取消引用它是不可能的:编译器不知道它指向哪个对象类型,因此根据对象的类型,它无法生成代码来做正确的事情

You can't dereference it because the compiler doesn't know what it is. 你不能取消引用它,因为编译器不知道它是什么。 You have to cast it into an appropriate type (and the compiler has to assume you know what you are doing). 您必须将其转换为适当的类型(编译器必须假设您知道自己在做什么)。

void * pointers are best used where you are interfacing with stuff at a fairly low level (such as I/O drivers) where you care very little what the data you are dealing with, you just know you have a buffer and a size. void *指针最适合用于与相当低级别的东西(例如I / O驱动程序)接口,在那里你很少关心你正在处理的数据,你只知道你有缓冲区和大小。

Any other use is fraught with danger. 任何其他用途都充满了危险。 For instance 例如

int i = 5;
void *p = &i;
.....
float *f = (float *)p;

This will get no compiler errors or warnings. 这将不会出现编译器错误或警告。 It's perfectly valid. 这完全有效。 But it is unlikely to do what you expect 但它不太可能达到你的预期

It can be useful to store a pointer and remain indifferent to its type. 存储指针并对其类型保持无关紧要可能很有用。 This is what void* is for. 这就是void *的用途。 It is one approach you can take when designing a storage container (linked list, hash map) in pure C. 在纯C中设计存储容器(链表,哈希映射)时,您可以采用一种方法。

If you wanted to make use of the pointer then you would have to track its type as well as its value, since you cannot arbitrarily deference pointers, and all type information is lost when you cast to void*. 如果你想使用指针那么你必须跟踪它的类型及其值,因为你不能随意地引用指针,并且当你转换为void *时所有类型信息都会丢失。

In your example, you could use a simple structure with a void* and a type field. 在您的示例中,您可以使用带有void *和type字段的简单结构。

In C++ you can achieve these things with polymorphic structures and even templates: what you are doing is far more C style. 在C ++中,您可以使用多态结构甚至模板来实现这些功能:您所做的更多是C风格。

You cannot print e here using void* without typecasting. 在没有类型转换的情况下,您无法使用void*在此处打印e A pointer is not just a simple variable which store the address, but it has got a type too which tells the compiler how much size it should read using that address. 指针不仅仅是一个存储地址的简单变量,但它也有一个类型,它告诉编译器使用该地址读取的大小。 A void* , as it do not posses any type, cannot be dereferenced without typecasting. 如果没有类型转换,则无法取消引用void* ,因为它没有任何类型。 By typecasting, you tell the compiler how much bytes it should read starting from the address that pointer carries. 通过类型转换,您可以告诉编译器从指针携带的地址开始应该读取多少字节。

void* provides an easy way for the programmer to easily store and use pointers of other types. void*为程序员提供了一种轻松存储和使用其他类型指针的简便方法。 We cannot use unsigned int or similar to store the value of a pointer since the size of a pointer is dependent on the processor. 我们不能使用unsigned int或类似的来存储指针的值,因为指针的大小依赖于处理器。 Also, we can use void* to make pointer arguments/return value of functions more generic. 此外,我们可以使用void*使指针参数/函数的返回值更通用。

I thing so you want to store int pointer to void* pointer. 我的事情所以你想存储指向void *指针的int指针。 In that condition you may get warning like "cast to pointer from integer of different size".For that you first need to assign some memory void pointer related to integer, and then use that void pointer may be like follow, 在那种情况下,您可能会收到警告,例如“从不同大小的整数转换为指针”。为此您首先需要指定一些与整数相关的内存void指针,然后使用该void指针可能如下,

void *ptr = malloc(sizeof(int));
*((int*)ptr) = 5;
printf("%d\n",*((int*)ptr));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM