C++为什么字符串的地址尽管是十六进制格式,但不能存储在 long int 变量中?

In C++ why address of string, despite being in hexadecimal format, can't be stored in long int variable?

本文关键字:存储 但不能 long int 变量 格式 字符串 为什么 地址 十六进制 C++      更新时间:2023-10-16

我有以下代码:

#include <iostream>
using namespace std;
int main(){
    string texts[] = {"one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten"};
    return 0;
}

代码:

cout << &texts[0] << endl;

给出输出:

0x7ffc7869f3c0

但是,

long int address = &texts[0];

给出编译时间错误:

In function ‘int main()’:
5.cpp:9:29: error: invalid conversion from ‘std::__cxx11::string* {aka std::__cxx11::basic_string<char>*}’ to ‘long int’ [-fpermissive]
  long int address = &texts[0];

为什么我会遇到此错误?

地址是地址,而不是数字。地址上的算术操作通常毫无意义(并且指针算术微妙不同),例如,乘以两个地址是没有意义的。

您可以使用uintptr_tintptr_t。它是可以从地址和地址施放的积分类型。因此,您可以代码

 uintptr_t ia = (uintptr_t)(&texts[0]);

但是您通常不应。在我的Linux X86-64上,uintptr_t等于64位unsigned long

请记住,地址是处理器和操作系统和编译器,因此特定于系统。有时,它们在相同程序的"相同"执行之间有所不同(请阅读ASLR)。顺便说一句,在某些处理器上,地址比单个数字更复杂(例如,在1980年代x86处于16位模式)。

因此,如果您关心便携式C 代码(通常应该),则不需要将地址投入整体类型。

另一方面,如果要编码特定于处理器和操作系统的内容(例如,在低级系统呼叫上方的newmalloc的实现),您将关心地址中的各种位置,以便您可以将其施放(以不可便利的方式)。如果您要编码某些操作系统内核的虚拟内存子系统,您将更多地关心地址中的位等...

...

您的 cout << &texts[0]产生了一些实现特定的输出,这主要对于调试目的是有意义的(但对于其他东西来说并不多)。C 11标准足够模糊以允许任何其他输出(我的感觉是,任何地址的pinkroses的输出都符合标准的字母,但我可能是错误的)。因此,如果您关心可移植性,则不应依赖它(或任何具体的"编号"地址看起来像)。

更糟糕的是,从 uintptr_t到一些指针,也相反。它们可能是可能的,但通常仅在某些特定系统上。而且它们仅在某些特定情况下才有意义。大多数数字不会制作明智的指针(例如,因为您的虚拟地址空间永远不会满足或致密),因此您不应该非常谨慎地投射它们。

一个相关的概念是关于未定义的行为。有很多有趣的事情要读和说。

相关文章: