简体   繁体   English

不使用sizeof的数据类型的大小

[英]size of a datatype without using sizeof

I have a data type, say X , and I want to know its size without declaring a variable or pointer of that type and of course without using sizeof operator. 我有一个数据类型,比如X ,我想知道它的大小而不声明该类型的变量或指针,当然不使用sizeof运算符。

Is this possible? 这可能吗? I thought of using standard header files which contain size and range of data types but that doesn't work with user defined data type. 我想过使用标准头文件,其中包含数据类型的大小和范围,但不适用于用户定义的数据类型。

To my mind, this fits into the category of "how do I add two ints without using ++, += or + ?". 在我看来,这符合“如何在不使用++,+ =或+?”的情况下添加两个整数的类别。 It's a waste of time. 这是浪费时间。 You can try and avoid the monsters of undefined behaviour by doing something like this. 你可以尝试通过做这样的事情来避免未定义行为的怪物。

size_t size = (size_t)(1 + ((X*)0));

Note that I don't declare a variable of type or pointer to X . 请注意,我没有声明类型的变量或指向X指针。

Look, sizeof is the language facility for this. 看, sizeof 这方面的语言设施。 The only one, so it is the only portable way to achieve this. 唯一的,所以它是实现这一目标的唯一便携方式。

For some special cases you could generate un-portable code that used some other heuristic to understand the size of particular objects[*] (probably by making them keep track of their own size), but you'd have to do all the bookkeeping yourself. 对于某些特殊情况,您可以生成不可移植的代码,使用其他启发式来了解特定对象的大小[*](可能通过让它们跟踪自己的大小),但您必须自己完成所有的簿记。

[*] Objects in a very general sense rather than the OOP sense. [*]对象在一般意义上而不是OOP意义上。

Well, I am an amateur..but I tried out this problem and I got the right answer without using sizeof. 好吧,我是一个业余爱好者..但我尝试了这个问题,我得到了正确的答案,没有使用sizeof。 Hope this helps.. I am trying to find the size of an integer. 希望这会有所帮助..我试图找到一个整数的大小。

int *a,*s, v=10;

a=&v;

s=a;

a++;

int intsize=(int)a-(int)s;

printf("%d",intsize);

这个采访问题的正确答案是“为什么我会这样做,当sizeof()为我这样做,并且这是唯一可行的方法吗?”

The possibility of padding prevent all hopes without the knowledge of the rules used for introducing it. 填充的可能性在不知道用于引入它的规则的情况下阻止了所有希望。 And those are implementation dependent. 这些都是依赖于实现的。

You could puzzle it out by reading the ABI for your particular processor, which explains how structures are laid out in memory. 您可以通过阅读特定处理器的ABI来解决它,这解释了结构在内存中的布局。 It's potentially different for each processor. 每个处理器可能有所不同。 But unless you're writing a compiler it's surprising you don't want to just use sizeof , which is the One Right Way to solve this problem. 但除非您正在编写编译器,否则您不希望仅使用sizeof ,这是解决此问题的一种正确方法。

Try this: 试试这个:

int a;
printf("%u\n", (int)(&a+1)-(int)(&a));

Look into the compiler sources. 查看编译器源代码。 You will get : 你会得到 :

  • the size of standard data types. 标准数据类型的大小。
  • the rules for padding of structs 填充结构的规则

and from this, the expected size of anything. 从这个,任何东西的预期大小。

If you could at least allocate space for the variable, and fill some sentinel value into it, you could change it bit by bit, and see if the value changes, but this still would not tell you any information about padding. 如果你至少可以为变量分配空间,并在其中填充一些sentinel值,你可以一点一点地改变它,看看值是否改变,但是这仍然不会告诉你任何关于填充的信息。

if X is datatype: 如果X是数据类型:

#define SIZEOF(X) (unsigned int)( (X *)0+1 )

if X is a variable: 如果X是变量:

#define SIZEOF(X) (unsigned int)( (char *)(&X+1)-(char *)(&X) )

Try This: 试试这个:

 #include<stdio.h>

int main(){

  int *ptr = 0;

  ptr++;
  printf("Size of int:  %d",ptr);

  return 0;

Available since C89 solution that in user code: 自用户代码中的C89解决方案可用:

  1. Does not declare a variable of type X. 不声明X类型的变量。
  2. Does not declare a pointer to type X. 不声明指向X的类型的指针。
  3. Without using sizeof operator. 不使用sizeof运算符。

Easy enough to do using standard code as hinted by @steve jessop 使用@steve jessop暗示的标准代码很容易

offsetof(type, member-designator)

which expands to an integer constant expression that has type size_t , the value of which is the offset in bytes, to the structure member ..., from the beginning of its structure ... C11 §7.19 3 它扩展为一个整数常量表达式,其类型为size_t ,其值是以字节为单位的偏移量,从结构的开头...到结构成员......C11§7.193

#include <stddef.h>
#include <stdio.h>

typedef struct {
  X member;
  unsigned char uc;
} sud03r_type;

int main() {
  printf("Size X: %zu\n", offsetof(sud03r_type, uc));
  return 0;
}

Note: This code uses "%zu" which requires C99 onward. 注意:此代码使用"%zu" ,这需要C99向前。

This is the code: The trick is to make a pointer object, save its address, increment the pointer and then subtract the new address from the previous one. 这是代码:诀窍是创建一个指针对象,保存其地址,递增指针,然后从前一个地址中减去新地址。 Key point is when a pointer is incremented, it actually moves by the size equal to the object it is pointing, so here the size of the class (of which the object it is pointing to). 关键点是当指针递增时,它实际上移动的大小等于它指向的对象,所以这里是类的大小(它指向的对象)。

#include<iostream>
using namespace std;
 class abc
    {
           int a[5];
           float c;           
    };
main()
{
    abc* obj1;
    long int s1;
    s1=(int)obj1; 
    obj1++;
    long int s2=(int)obj1;
    printf("%d",s2-s1);
}

Regards 问候

A lot of these answers are assuming you know what your structure will look like. 很多这些答案都假设你知道你的结构会是什么样子。 I believe this interview question is intended to ask you to think outside the box. 我相信这个面试问题的目的是要求你跳出框框思考。 I was looking for the answer but didn't find any solutions I liked here. 我正在寻找答案,但没有找到我喜欢的任何解决方案。 I will make a better assumption saying 我会做出更好的假设

struct foo {
  int a;
  banana b;
  char c;
  ...
};

By creating foo[2], I will now have 2 consecutive foo objects in memory. 通过创建foo [2],我现在将在内存中有2个连续的foo对象。 So... 所以...

foo[2] buffer = new foo[2];
foo a = buffer[0];
foo b = buffer[1];

return (&b-&a);

Assuming did my pointer arithmetic correctly, this should be the ticket - and its portable! 假设我的指针算法正确,这应该是票 - 它的便携性! Unfortunately things like padding, compiler settings, etc.. would all play a part too 不幸的是,诸如填充,编译器设置等等也都会起作用

Thoughts? 思考?

put this to your code 把它放到你的代码中

then check the linker output ( map file) 然后检查链接器输出(映射文件)

unsigned int  uint_nabil;
unsigned long  ulong_nabil;

you will get something like this ; 你会得到这样的东西;

uint_nabil 700089a8 00000004
ulong_nabil 700089ac    00000004

4 is the size !! 4是大小!!

One simple way of doing this would be using arrays. 一种简单的方法是使用数组。 Now, we know for the fact that in arrays elements of the same datatype are stored in a contiguous block of memory. 现在,我们知道在数组中,相同数据类型的元素存储在连续的内存块中。 So, by exploiting this fact I came up with following: 所以,通过利用这个事实我想出了以下内容:

#include <iostream>
using namespace std;

int main()
{
    int arr[2];
    int* ptr = &arr[0];
    int* ptr1 = &arr[1];
    cout <<(size_t)ptr1-(size_t)ptr;
}

Hope this helps. 希望这可以帮助。

# include<stdio.h>

struct node
{
  int a;
  char c;
};

void main()
{
   struct node*ptr;
   ptr=(struct node*)0;
   printf("%d",++ptr);
}
#include <stdio.h>

struct {
  int a;
  char c;
};

void main() {
  struct node*temp;
  printf("%d",(char*)(temp+1)-(char*)temp);
}
    main()    
    {
    clrscr();
    int n;
    float x,*a,*b;//line 1
    a=&x;
    b=(a+1);
    printf("size of x is %d",
    n=(char*)(b)-(char*)a);
    }

By this code script the size of any data can be calculated without sizeof operator.Just change the float in line 1 with the type whose size you want to calculate 通过此代码脚本,可以在不使用sizeof运算符的情况下计算任何数据的大小。只需要更改第1行中的float,其类型为要计算的大小

Try this, 试试这个,

#define sizeof_type( type )  ((size_t)((type*)1000 + 1 )-(size_t)((type*)1000))

For the following user-defined datatype, 对于以下用户定义的数据类型,

struct x
{
    char c;
    int i;
};

sizeof_type(x)          = 8
(size_t)((x*)1000 + 1 ) = 1008
(size_t)((x*)1000)      = 1000

This takes into account that a C++ byte is not always 8 binary bits, and that only unsigned types have well defined overflow behaviour. 这考虑到C ++字节并不总是8个二进制位,并且只有无符号类型具有明确定义的溢出行为。

#include <iostream>
int main () {
    unsigned int i = 1;
    unsigned int int_bits = 0;
    while (i!=0) {
        i <<= 1;
        ++int_bits;
    }

    unsigned char uc = 1;
    unsigned int char_bits = 0;
    while (uc!=0) {
        uc <<= 1;
        ++char_bits;
    }

    std::cout << "Type int has " << int_bits << "bits.\n";
    std::cout << "This would be  " << int_bits/8 << " IT bytes and "
              << int_bits/char_bits << " C++ bytes on your platform.\n";
    std::cout << "Anyways, not all bits might be usable by you. Hah.\n";
}

Surely, you could also just #include <limit> or <climits> . 当然,你也可以#include <limit><climits>

#include <bits/stdc++.h> 

using namespace std; 

int main() 
{ 

    // take any datatype hear 
    char *a = 0; // output: 1

    int  *b = 0;  // output: 4

    long *c = 0; // output: 8

    a++;

    b++;

    c++;

    printf("%d",a);

    printf("%d",b);

    printf("%d",c);

    return 0; 
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM