【问题标题】:How to measure the size of int and short variable by memory allocating features?如何通过内存分配功能测量 int 和 short 变量的大小?
【发布时间】:2014-04-13 03:07:51
【问题描述】:

我尝试在我的电脑(X86_64)中测试intshort类型的长度,所以我写了两段代码如下: 简短:

short a;
scanf("%hd%hd",&a,&a+1);
printf("%hd",a+*(&a+1));

int:

int a;
scanf("%d%d",&a,&a+1);
printf("%d",a+*(&a+1));

两者都工作并输出正确答案,但是当我将数字 1 更改为 4 时,第一个效果很好,而第二个在输入后显示 Segmentation fault
有资料说short和int的长度在x86中都是16位的,不知道x86_64有什么区别,是一样的吗? 另外,是什么导致了Segmentation fault

PS:我用gcc -Wall -O2 -o filename -lm编译。

【问题讨论】:

  • 您为什么认为上面的代码可以帮助您确定任何类型的大小?
  • 您可以使用sizeof 表达式来确定类型的大小。 printf("%d\n", (int) sizeof(short));

标签: c compiler-construction x86-64


【解决方案1】:

所有 x86 ABI 都定义 sizeof(short) == 2
所有 x86 16 位 ABI 定义 sizeof(int) == 2,所有其他 x86 ABI 定义 sizeof(int) == 4。 对于标准 64 位模式,每个指针都是 64 位 == 8 字节大,对于 64 位 4G 地址模式和 32 位平面内存模式(平面是标准的),每个指针都是 32 位 == 4 字节,而对于 16 位模式,它会有所不同。

此示例具有未定义行为,因为您在&a+1 处不拥有short 对象:

short a;
scanf("%hd%hd",&a,&a+1);
printf("%hd",a+*(&a+1));

这个也一样,只是int

int a;
scanf("%d%d",&a,&a+1);
printf("%d",a+*(&a+1));

未定义行为表示任何事情都可能发生,即使是众所周知的鼻恶魔。
这包括它似乎工作以及重新格式化您的驱动器

【讨论】:

    【解决方案2】:

    您可以通过以下方式获取short的大小:

    printf("size of short: %d\n", sizeof(short));
    

    你可以得到short指针的大小,通过:

    printf("size of pointr: %d\n", sizeof(short*));
    

    我相信 Deduplicator 已经回答了您的其他问题。

    【讨论】:

    • sizeof(void *) 可能与 sizeof(other_type *) 不同。在现代系统上,当您没有有限的地址空间时,它们是最方便的方法;但并非总是如此。
    • @MattMcNabb 我觉得你总是在那里拓宽我的 C++ 知识。有时它很烦人。大多数时候它是有教育意义的。你有提到这块金块吗?
    • 在标准的[basic.compound] 中,“指针类型的值表示是实现定义的”。术语值表​​示在上一节中定义为“保存类型T值的位集合”;当我们谈论指针时,指针是保存指针的一组位,而不是指向的东西。给出了几种情况,指向两个特定类型的指针必须具有相同的表示和对齐方式,但没有通用条款规定所有指针都具有相同的表示和对齐方式。
    • @MattMcNabb 我从你那里学到的另一件事。谢谢你。顺便说一句,我刚刚更新了我的答案以反映我的新理解。
    • %d 需要 int 参数; sizeof 产生 size_t。要么将参数传递给int,要么使用%zu(如果你的实现支持它;微软可能不支持)。
    【解决方案3】:

    阅读您的 cmets 和答案后,我知道我的代码有什么问题。
    我猜变量的地址就像汇编语言中的那样,所以如果我得到一个地址并将其与变量的长度相加,我可以获得以下可行的地址。我先用&a+4来测试int的长度是不是4 BYTES,但是运行的时候有Segmentation fault,我把4改成1,得到正确的值,没看懂为什么这行得通?现在,我明白了。
    在以下代码中:

    short a,b;
    a = b = 1024;
    cout << &a << endl << &b << endl;
    cout << &a << endl << (&a) + 1;
    

    它的输出是:

    0xbfad153c  
    0xbfad153e  
    0xbfad153c  
    0xbfad153e 
    

    还有

    int a,b;
    a = b = 1024;
    cout << &a << endl << &b << endl;
    cout << &a << endl << (&a) + 1;
    return 0;
    

    输出是:

    0xbfddb968  
    0xbfddb96c  
    0xbfddb968  
    0xbfddb96c  
    

    这里显示&amp;a + 1加上int a的大小值而不是1literal const value
    所以我只想用内存分配的特性来测量intshort的大小,而不是sizeof函数。
    感谢您的回答和 cmets,即使它们不是我想要的。

    【讨论】:

    • 下面的变量是哪个变量?取决于编译器、编译器标志、确切来源和编译时的确切情况(它是不稳定的)。此外,您不用 C++ 中的 地址算术,而是执行 指针算术,这意味着内置的指针类型具有自动缩放功能。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多