今天我在玩 C++ 时遇到了这个问题,我认为这很奇怪,但可能更可能是由于我的误解和最近缺乏纯 C 编码。
我最初想做的是将双精度转换为无符号字符数组。我的理解是,双精度的 64 位(sizeof(double) 为 8)现在将表示为 8 个 8 位字符。为此,我使用了 reinterpret_cast。
所以这里有一些从 double 转换为 char 数组的代码,或者至少我认为这就是它所做的。问题是它从 strlen 返回 15 而不是 8,为什么我不确定。
double d = 0.3;
unsigned char *c = reinterpret_cast<unsigned char*> ( &d );
std::cout << strlen( (char*)c ) << std::endl;
所以 strlen 是我的第一个问题。但后来我尝试了以下,发现它返回了 11、19、27、35。这些数字之间的差异是 8,所以在某种程度上是正确的。但是为什么这不返回 15, 15, 15, 15,(因为它在上面的代码中返回 15 )。
double d = 0.3;
double d1 = 0.3;
double d2 = 0.3;
double d3 = 0.3;
unsigned char *c_d = reinterpret_cast<unsigned char*> ( &d );
unsigned char *c_d1 = reinterpret_cast<unsigned char*> ( &d1 );
unsigned char *c_d2 = reinterpret_cast<unsigned char*> ( &d2 );
unsigned char *c_d3 = reinterpret_cast<unsigned char*> ( &d3 );
std::cout << strlen( (char*)c_d ) << std::endl;
std::cout << strlen( (char*)c_d1 ) << std::endl;
std::cout << strlen( (char*)c_d2 ) << std::endl;
std::cout << strlen( (char*)c_d3 ) << std::endl;
所以我查看了字符的地址,它们是。
0x28fec4
0x28fec0
0x28febc
0x28feb8
现在这是有道理的,因为我的系统上 unsigned char* 的大小是 4 个字节,但我认为正确的内存量将从演员表中分配,否则 reinterpret_cast 似乎是一件非常危险的事情......此外,如果我愿意
for (int i = 0; i < 4; ++i) {
double d = 0.3;
unsigned char *c = reinterpret_cast<unsigned char*> ( &d );
std::cout << strlen( (char*)c ) << std::endl;
}
这将打印 11、11、11、11!
所以这里发生了什么,显然内存在某些地方被覆盖,重新解释演员表没有像我想象的那样工作(即我用错了)。在 C++ 中使用字符串已经很长时间了,有时当你回到原始 char 数组时,你会忘记这些事情。
所以我想这是一个三部分的问题。
为什么 strlen 最初返回 15?为什么 4 个 strlen 调用的大小变大了?为什么循环返回 11、11、11、11?
谢谢。