简体   繁体   English

C++ 类型转换 int 指针到 void 指针到 char 指针?

[英]C++ Typecast int pointer to void pointer to char pointer?

Hello im confused by typecasting pointers.您好,我对类型转换指针感到困惑。 I understand that void can hold any type.我知道 void 可以容纳任何类型。

So if i have an int * with a value inside of it then i make a void * to the int * can i then typecast it to a char?因此,如果我有一个 int *,其中有一个值,那么我对 int * 做了一个 void *,然后我可以将它类型转换为 char 吗?

It's quite hard to explain what i mean and the title might be wrong but will this work?很难解释我的意思,而且标题可能是错误的,但这会起作用吗?

And is it safe to do this.这样做是否安全。 I've seen it used quite alot in C.我已经看到它在 C 中使用了很多。 Is this bad practise.这是不好的做法吗。

int main() {
    int* a = new int{ 65 };
    void* v = static_cast<int*>(a);
    std::cout << *(static_cast<char *>(v));
}

I understand that void can hold any type.我知道 void 可以容纳任何类型。

You understand it wrong.你理解错了。 Pointer does not hold data, it points to it.指针不保存数据,它指向它。 So integer pointer points to memory with holds integer, float pointer points where float is etc. Void pointer just points to some memory, but it says - I do not know what kind of data is there. So integer pointer points to memory with holds integer, float pointer points where float is etc. Void pointer just points to some memory, but it says - I do not know what kind of data is there.

Now conversion.现在转换。 Technically you can convert almost any pointer to any (there are exceptions like function pointers or pointers to a member, but they are completely different beasts and it is not what you are asking about) as they all just pointers.从技术上讲,您几乎可以将任何指针转换为任何指针(有例外,例如 function 指针或指向成员的指针,但它们是完全不同的野兽,这不是您要问的),因为它们都只是指针。 But problem happens when you try to access memory where they point to.但是当您尝试访问它们指向的 memory 时,就会出现问题。 So if you have int in memory and try to read it as float or vice versa - that's illegal.因此,如果您在 memory 中有int并尝试将其读取为float ,反之亦然 - 这是非法的。 Now therte is one exception - you can access any data through pointer to char (or unsigned char ) as char represents byte .现在 rte 是一个例外 - 您可以通过指向char (或unsigned char )的指针访问任何数据,因为char代表byte Void pointer is irrelevant here, you can convert from pointer of one type to another without void * involved: void 指针在这里无关紧要,您可以在不涉及void *的情况下从一种类型的指针转换为另一种类型的指针:

int main() {
    int* a = new int{ 65 };
    unsigned char *uptr = reinterpret_cast<unsigned char *>( a );
    for( size_t i = 0; i < sizeof(int); ++i )
        std::cout << static_cast<unsigned int>( uptr[i] ) << ' ';
}

Live example活生生的例子

Note I casted uptr[i] to unsigned int, that is to print bytes as numbers, as C++ stream ( std::cout in this case) will print character as symbol, which would be meaningless in this case.注意我将uptr[i]转换为 unsigned int,即将字节打印为数字,因为 C++ stream (在这种情况下为std::cout )将字符打印为符号,在这种情况下这将毫无意义。

First any object pointer can be cast to void* .首先,任何 object 指针都可以转换为void* That's the generic "could be anything" solution inherited from C and you should not use it.这是从 C 继承的通用“可能是任何东西”解决方案,您不应该使用它。 The C++ way is to use template<typename T> and T* for such cases where you need an anything pointer. C++ 方法是在需要任何指针的情况下使用template<typename T>T*

Secondly any object pointer can also be cast to char * as a special case.其次,任何 object 指针也可以作为特殊情况强制转换为char * Casting to char* gives you access to the memory representation of the object.转换为char*可让您访问 object 的 memory 表示。 It does not convert the object to a char or anything, you get access to the raw bits for the value stored in the object.它不会将 object 转换为 char 或任何内容,您可以访问存储在 object 中的值的原始位。

So the reason why casting to void* and then to char* works is that casting any object pointer to char* is valid.因此,转换为void*然后转换为char*起作用的原因是,将任何 object 指针转换为char*都是有效的。 The intermediate step to void* is not needed at all.根本不需要void*的中间步骤。

This only works for char* or unsigned char* or any other variant of char pointer, including std::byte* .这仅适用于char*unsigned char*char指针的任何其他变体,包括std::byte* You can not static_cast an int* to float* for example and using a void* and intermediate step will not make that work either.例如,您不能 static_cast 将int*转换为float*并且使用void*和中间步骤也不会使其工作。

Note: The value printed by the code is implementation defined since the memory representation of an int and a char is defined by the implementation.注意:代码打印的值是实现定义的,因为 int 和 char 的 memory 表示由实现定义。 Specifically their endianness and size of an int and the signedness of char.特别是它们的字节顺序和 int 的大小以及 char 的符号。 Apart from that it perfectly valid code.除此之外,它完全有效的代码。

The question though is: Why do you want to do this?但问题是:你为什么要这样做?

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

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