【问题标题】:How much bytes does an address take?一个地址占用多少字节?
【发布时间】:2013-10-25 19:29:46
【问题描述】:

基本上我的问题是单个地址占用/拥有多少字节?

我的意思是 char 在我的平台上占用 1 个字节并有 1 个地址。但是int 需要 4 个字节。这个int 占用多少个地址?它仍然只有 1 个地址还是有 4 个?

例如:

char c = 'A'; //Address at 0xdeadbeee
int i = 45846; //Address at 0xdeadbeef
int* iPtr = &i;
iPtr++; //Address at 0xdeadbef3 now

0xdeadbeef0xdeadbef3 之间的地址会发生什么情况?它们都是为i 保留的吗?当我指向0xdeadbeee(应该是一个地址| 字节或i 下的任何内容)并更改它的值时,我会发生什么?

编辑: 对于那些仍然会回答的人,我不想知道整数有多大。我想知道在占用 4 个字节的内存时它是否也有 4 个地址,以及在更改其中一个地址的值时会发生什么(如果它有 4 个地址)。

我希望现在更清楚了。

【问题讨论】:

  • 每个字节都是可寻址的,但int只有一个地址。
  • “基本上我的问题是单个地址占用/拥有多少字节?” -> sizeof(T *) 会告诉你。但是您的问题实际上与“地址的大小”无关。再一次,您在问为什么指针算术以它的工作方式工作。
  • Pointer Arithmetic 的可能重复项
  • @JonathanWood “地址的大小不取决于数据的大小。” - 实际上,在 C 中,sizeof(T1 *) == sizeof(T2 *)...
  • 在大多数处理器上(有人有反例吗?),内存是面向字节的,即每个字节都有一个唯一的地址。所以,从字面上看,int 确实有 4 个地址。

标签: c memory


【解决方案1】:

内置类型(char、short、int、long)的大小是特定于实现和平台的。如果我们假设您的 int 是 32 位,那么我们可以解决您的一些问题:

如果i 驻留在0xdeadbeef,那么0xdeadbeef, 0xdeadbef0, 0xdeadbef1, and 0xdeadbef2 字节地址将全部用于存储i。如果您将iPtr 设置为0xdeadbeee 并写入一个值,0xdeadbeee 和以下三个地址将包含您写入的值。如果您随后尝试读取 ci,您会发现值已损坏。

需要考虑的一些事项:并非所有架构都允许字节寻址。 char 在您的系统上可能是一个字节,但由于限制,可能会保留 4 个字节。同样,您可能无法读取或写入指向非对齐地址的指针。例如,只能访问 32 位边界内存的系统只能访问 0xdeadbeec0xdeadbef0

【讨论】:

  • 谢谢!这是我一直在寻找的答案。
  • 根据 C 中的定义,char 是一个可寻址单元。在 C 模型中,每个字节都可以通过 char 指针寻址。如果底层硬件不支持直接寻址其字节,则 C 实现必须要么创建这样的寻址(通过加载整个单元并提取其中的一部分,相反通过合并部分并存储整个单元)或必须定义其char大小为硬件单元的大小。 char 对象不能有任何填充;它总是使用一个字节,但是 C 实现定义了一个“字节”。
  • 我承认这一点。我在考虑可以填充的结构和单个char 变量(静态、堆栈、全局)。不过,在示例代码中,使用了 int 指针。 C 标准是否解决了非char 类型的这种未对齐访问?
【解决方案2】:

你怎么会发现这个?怎么样:

printf("%zu\n", sizeof(iPtr));

但是,正如@H2CO3 指出的那样,您实际上是在询问pointer arithmetic。阅读更多内容以获取更多信息。

【讨论】:

  • 虽然这是对问题 how many bytes does the address have 的正确答案,但进一步的散文表明这不是 OP 真正想问的。
  • @ChristianTernus 如果我没记错的话,我得到的 iPtr 大小在我的平台上是 8 个字节。我已经知道尺寸了。我的问题是它是否有与字节一样多的地址。
【解决方案3】:

是的,地址&i+1byte是i的第二个字节的地址。

如果您住在 Memory Street 100 的 4 栋房屋中,则您有四个地址。但这些地址针对不同的建筑物。虽然,根据您的邮政服务,如果不是规范地址,邮件可能无法投递(内存访问也是如此 - 取决于平台)。

【讨论】:

  • &i+1int 的地址,i 之后。 (char *) &x + 1i的第二个字节的地址。
  • @EricPostpischil,对不起,我编辑的太多了。原来是 +1*byte* 然后我删除了字节和星星。会修。不应该是有效的表达,而是一种解释。
  • 很好的比喻,不过。考虑一封寄到“101, Memory St.”的信。 ——而邮递员实际上是在那个地址递送它。但是,如果您只在规范地址查看邮件,您可能永远看不到那封信。 (可悲的是,这个类比在这里被打破了:如果你在错误的 memory 地址上写了一些东西,你的 C 程序可能会崩溃。房子不会这样做。)
  • @Jongware,内存也没有,但邮递员可以,如果他完全没有准备好,整个邮政服务可能会崩溃;-)
【解决方案4】:

您可以使用sizeof 找出指针占用的字节数:

size_t int_ptr_size = sizeof(int*);

如果您尝试通过未正确对齐类型的指针访问数据,则会调用未定义的行为,因此无法预测会发生什么。在某些架构上,程序会因总线错误而崩溃。

【讨论】:

    【解决方案5】:

    地址是指数据的开始。所以地址的大小不会根据数据的大小而改变。

    但是,地址的实际大小将取决于平台。在许多较新的系统上,该大小将是 64 位。但如果不了解您的平台,我们就无法准确地说出。

    您可以在代码中使用sizeof() 来获取地址的大小。

    【讨论】:

      【解决方案6】:

      一切都取决于您的硬件平台内存组织。 如果内存以 4 字节单元组织,则长度小于或等于 4 字节的变量(假设内存调整正确)仅保存在一个内存单元中,因此仅由一个地址值指向。

      【讨论】:

        猜你喜欢
        • 2019-11-05
        • 1970-01-01
        • 2012-03-12
        • 2018-09-07
        • 2014-01-12
        • 2023-03-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多