【问题标题】:size of struct without use sizeof keyword不使用 sizeof 关键字的结构大小
【发布时间】:2010-08-02 12:09:37
【问题描述】:

这是不使用 sizeof 关键字返回结构大小的代码

#include <iostream>
using namespace std;
struct  point{
    int x;
    int y;
    };
struct point pt={0,0};

int main(){
    point *ppt=&pt;
    unsigned char *p1,*p2;
    p1=(unsigned char *)ppt;
    p2=(unsigned char *)++ppt;
    printf("%d",p2-p1);


     return 0;
}

据我所知,它返回 8,因为 sizeof char 是 1 个字节,并且此结构首先包含整数类型,它使用 char 指针将其转换为 char 并返回 sizeof char?或者?我不明白它是如何工作的 谢谢

【问题讨论】:

  • 正如在这个问题stackoverflow.com/questions/3387021/portability-of-the-code 中指出的那样,代码会导致未定义的行为。
  • @Neil:未定义的行为到底在哪里?我没看到。只要不取消引用结果指针,++ppt 就是合法的。
  • @Fred p2 不是有效指针,原因在我引用的问题中讨论过。
  • @Neil:你读过 5.7 §4 吗? “指向非数组对象的指针与指向长度为 1 且以对象类型作为其元素类型的数组的第一个元素的指针的行为相同”因此获得&amp;pt+1是合法的只要你不取消引用它。

标签: c++


【解决方案1】:

这里的演员表发生在 ++ 之后

p2 = (unsigned char *)++ppt;

之所以有效,是因为指针上的 ++ 会增加指针的字节数,使其等于指向的类型的大小。然后你转换为 char,因为减号将指针的差异除以类型的大小(所以除以 1,因为它现在是 char*)。

如果您打算使用它,需要注意一点 - sizeof 肯定是在编译时完成的,此时优化器可能会或可能不会将这段代码识别为常量表达式。

此外,正如评论者和其他问题所指出的那样,如果类型需要对齐,它将与 sizeof 不匹配(某些系统要求类型从可被 2、4 等整除的内存边界开始)。

最后,(来自 cmets),一旦指针被递增,它就无效并且不能被使用(即使是减法、比较——即即使是在不取消引用它的方式)

来自 C 基本原理文档: http://www.open-std.org/jtc1/sc22/wg14/www/C99RationaleV5.10.pdf

标准中隐含的概念 的无效指针。在讨论中 指针,标准通常 指“指向对象的指针”或 “指向函数的指针”或“空值” 指针。”地址的一个特例 算术允许指针指向 刚刚超过数组的末尾。任何 其他指针无效。

一个无效的指针可能被创建在 几种方式。任意值可以 (通过强制转换)分配给指针 多变的。 (这甚至可以创建一个 有效的指针,取决于 值。)指向对象的指针变为 如果内存包含 对象被释放或移动 重新分配。指针运算可以 产生超出范围的指针 一个数组。

不管无效指针如何 创建,任何使用它都会产生 未定义的行为。甚至任务, 与空指针比较 常数,或与自身比较, 可能在某些系统上导致 例外。

考虑一个假设的分段 架构上的指针 包括一个段描述符和一个 抵消。假设段是 相对较小,因此较大的阵列 被分配在多个段中。 虽然段是有效的 (分配,映射到实际内存), 硬件、操作系统或 C 实现可以使这些多个 段的行为类似于单个对象: 指针算术和关系 运营商使用定义的映射到 将正确的顺序强加于 数组的元素。一旦回忆 已解除分配,映射为否 更保证存在。的使用 段描述符现在可能会导致 异常,或硬件寻址 逻辑可能会返回无意义的数据。

【讨论】:

  • 自增ppt后,不再指向有效对象。之后对 ppt 的任何使用都会导致未定义的行为。这可能是今天第五次讨论此类问题。 ://
  • “今天已经第五次讨论这种类型的问题了”——我闻起来像一个愚蠢的家庭作业吗? ;)
  • @msw:要么那个,要么采访。 :-)
  • @mfukar 你不能取消引用它,但你可以使用指针的值。否则,STL 中的 .end() 之类的东西就不起作用了。
  • @Lou end() 与数组一起使用,您可以在数组末尾添加一个 - OP 的代码中没有数组。
【解决方案2】:
struct  ABC{
    int a;
    float b;
    char c;
};
int main(){
    struct ABC *ptr=(struct ABC *)0;
    ptr++;
    printf("Size of structure is: %d",*ptr);
    return 0;
}

这是在不使用sizeof 的情况下查找struct 大小的另一种方法。

【讨论】:

  • 这实际上给出了分段错误,您不应该遵循 ptr 而只是指向第 0 个地址之后的位置。
猜你喜欢
  • 1970-01-01
  • 2011-02-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-07
  • 1970-01-01
  • 2021-05-06
相关资源
最近更新 更多