我应该使用哪个 *_cast 将任意整数类型指针转换为 char 指针?

Posted

技术标签:

【中文标题】我应该使用哪个 *_cast 将任意整数类型指针转换为 char 指针?【英文标题】:Which *_cast should I use to cast an arbitrary integer-type pointer to a char pointer? 【发布时间】:2014-03-11 02:49:05 【问题描述】:

我需要用 /dev/urandom 中的数据填充一个整数类型变量(任意大小)。考虑到这一点,我有以下代码:

std::fstream fstr("/dev/urandom", std::fstream::in | std::fstream::binary);
fstr.read(reinterpret_cast<char*>(&randomseed), sizeof(randomseed));
fstr.close();

randomseed 是我需要用随机数据填充的变量)。

这会做正确的事(即无论库实现如何,它都是安全的),还是我应该使用其他一些 *_cast?

【问题讨论】:

你选对了演员,这是reinterpret_cast,但不要忘记错误处理,阅读后检查流对象的错误标志。 @pasztorpisti 当然,为了简洁起见,我只是不想在代码 sn-p 中包含它。谢谢! @Veeno 不错,不客气。 【参考方案1】:

这不安全。只有char 类型保证没有陷阱表示。

“正确”的解决方案是将 /dev/urandom 包装在 C++ &lt;random&gt; 引擎中,并使用 std::uniform_int_distribution

【讨论】:

我究竟如何将/dev/random 包装在&lt;random&gt; 引擎中?我的意思是,我知道我在这里做的是“hacky”,但&lt;random&gt; 引擎实现本身在某些时候是否必须有类似的“hack”?更安全的解决方案是不使用istream::read 而是使用istream::get 来一次从/dev/random 中获取一个字节? @Veeno:现有引擎不受大多数​​ UB 规则的约束,因为它们被视为实现的一部分,并且可能依赖于实现的其他部分。也就是说,您当然可以一次读取 4 个字节并将它们放入 unsigned long - 只需将第二个字节移动 8 位,将第三个字节移动 16 位,将第四个字节移动 24 位。由于操作是数字的并且在类型的范围内,因此您没有陷阱问题。当然,这可能会使一些位为零,但这对于随机引擎来说不是问题。分布会使用随机引擎的最小值/最大值来处理这个问题。 嗯...为什么我一次可以从/dev/urandom 中读取四个字节,但不能读取一个? :( 读取一个char 不意味着只读取一个字节吗?我可以读取四个字节sizeof(randomseed) 次,将每个四个字节按位异或到一个字节,相应地移位并用随机数据填充变量randomseed ,但这似乎非常浪费——我宁愿只从/dev/urandom 中读取我需要的数据。 呃,恐怕你真的没听懂。你可以读一个,只是不是很随机(只有 256 种可能性)。此外,您似乎非常坚持sizeof(randomseed),但这是一个毫无意义的数字。不会告诉您允许的值范围。为此,您有std::numeric_limits,然后您可以使用它来选择合适的std::uniform_int_distribution 好吧,我被“困”在sizeof(randomseed) 上,因为这告诉我需要从/dev/urandom 中读出多少字节才能用随机数据填充整个randomseed... 是的,一个字节只有 256 种可能性,我知道,但是如果我读取四个字节,那仍然是 256^4 = 2^32 种可能性,无论我是一次读取一个还是一次读取全部四个。

以上是关于我应该使用哪个 *_cast 将任意整数类型指针转换为 char 指针?的主要内容,如果未能解决你的问题,请参考以下文章

使用static_cast进行父类指针转子类指针可能出现的问题

reinterpret_cast and const_cast

[C/C++]_[中级]_[static_cast的详细解析]

[C/C++]_[中级]_[static_cast的详细解析]

reinterpret

delphi 怎么把任意类型的指针转换成integer??一个关于tag的问题,