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

时间:2021-06-21 16:34:43

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.

这是可能的吗?我曾想过使用包含数据类型的大小和范围的标准头文件,但这不适用于用户定义的数据类型。

20 个解决方案

#1


42  

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.

在我看来,这属于“如何在不使用+、+=或+的情况下添加两个int”的范畴。这是浪费时间。你可以尝试通过做这样的事情来避免不明确的行为。

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

Note that I don't declare a variable of type or pointer to X.

注意,我没有声明类型或指向X的指针的变量。

#2


12  

Well, I am an amateur..but I tried out this problem and I got the right answer without using sizeof. Hope this helps.. I am trying to find the size of an integer.

我是个业余爱好者。但是我尝试了这个问题,没有使用sizeof我得到了正确的答案。希望这可以帮助. .我试图找到一个整数的大小。

int *a,*s, v=10;

a=&v;

s=a;

a++;

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

printf("%d",intsize);

#3


11  

Look, sizeof is the language facility for this. The only one, so it is the only portable way to achieve this.

看,sizeof是这个的语言工具。这是唯一的,这是唯一的可移植方式。

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意义上的对象。

#4


6  

The correct answer to this interview question is "Why would I want to do that, when sizeof() does that for me, and is the only portable method of doing so?"

这个面试问题的正确答案是“为什么我要这么做,当sizeof()为我做这个,并且是唯一的可移植的方法?”

#5


4  

The possibility of padding prevent all hopes without the knowledge of the rules used for introducing it. And those are implementation dependent.

如果不了解引入规则的规则,填充的可能性会阻止所有的希望。这些都依赖于实施。

#6


3  

You could puzzle it out by reading the ABI for your particular processor, which explains how structures are laid out in memory. 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.

您可以通过阅读特定处理器的ABI来解决这个问题,它解释了如何在内存中布局结构。它对每个处理器都可能不同。但是除非你正在编写编译器,否则你不希望仅仅使用sizeof,这是解决这个问题的唯一正确的方法。

#7


3  

Try this:

试试这个:

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

#8


2  

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.

如果您至少可以为变量分配空间,并在其中填充一些前哨值,那么您可以一点一点地更改它,并查看值是否更改,但这仍然不能告诉您任何有关填充的信息。

#9


2  

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) )

#10


2  

Try This:

试试这个:

 #include<stdio.h>

int main(){

  int *ptr = 0;

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

  return 0;

#11


0  

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

问候

#12


0  

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. So...

通过创建foo[2],我现在在内存中有两个连续的foo对象。所以…

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?

想法吗?

#13


0  

Available since C89 solution that in user code:

自C89解决方案以来,在用户代码:

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

Easy enough to do using standard code as hinted by @steve jessop

使用@steve jessop提示的标准代码非常简单

offsetof(type, member-designator)

offsetof(类型、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.19 - 3

#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继续。

#14


0  

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是尺寸!!

#15


0  

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.

希望这个有帮助。

#16


-1  

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

#17


-1  

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

#18


-1  

    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运算符来计算。只需将第一行中的浮点数更改为您希望计算其大小的类型

#19


-1  

#include <stdio.h>

struct {
  int a;
  char c;
};

void main() {
  struct node*temp;
  printf("%d",(char*)(temp+1)-(char*)temp);
}

#20


-1  

# include<stdio.h>

struct node
{
  int a;
  char c;
};

void main()
{
   struct node*ptr;
   ptr=(struct node*)0;
   printf("%d",++ptr);
}

#1


42  

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.

在我看来,这属于“如何在不使用+、+=或+的情况下添加两个int”的范畴。这是浪费时间。你可以尝试通过做这样的事情来避免不明确的行为。

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

Note that I don't declare a variable of type or pointer to X.

注意,我没有声明类型或指向X的指针的变量。

#2


12  

Well, I am an amateur..but I tried out this problem and I got the right answer without using sizeof. Hope this helps.. I am trying to find the size of an integer.

我是个业余爱好者。但是我尝试了这个问题,没有使用sizeof我得到了正确的答案。希望这可以帮助. .我试图找到一个整数的大小。

int *a,*s, v=10;

a=&v;

s=a;

a++;

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

printf("%d",intsize);

#3


11  

Look, sizeof is the language facility for this. The only one, so it is the only portable way to achieve this.

看,sizeof是这个的语言工具。这是唯一的,这是唯一的可移植方式。

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意义上的对象。

#4


6  

The correct answer to this interview question is "Why would I want to do that, when sizeof() does that for me, and is the only portable method of doing so?"

这个面试问题的正确答案是“为什么我要这么做,当sizeof()为我做这个,并且是唯一的可移植的方法?”

#5


4  

The possibility of padding prevent all hopes without the knowledge of the rules used for introducing it. And those are implementation dependent.

如果不了解引入规则的规则,填充的可能性会阻止所有的希望。这些都依赖于实施。

#6


3  

You could puzzle it out by reading the ABI for your particular processor, which explains how structures are laid out in memory. 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.

您可以通过阅读特定处理器的ABI来解决这个问题,它解释了如何在内存中布局结构。它对每个处理器都可能不同。但是除非你正在编写编译器,否则你不希望仅仅使用sizeof,这是解决这个问题的唯一正确的方法。

#7


3  

Try this:

试试这个:

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

#8


2  

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.

如果您至少可以为变量分配空间,并在其中填充一些前哨值,那么您可以一点一点地更改它,并查看值是否更改,但这仍然不能告诉您任何有关填充的信息。

#9


2  

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) )

#10


2  

Try This:

试试这个:

 #include<stdio.h>

int main(){

  int *ptr = 0;

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

  return 0;

#11


0  

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

问候

#12


0  

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. So...

通过创建foo[2],我现在在内存中有两个连续的foo对象。所以…

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?

想法吗?

#13


0  

Available since C89 solution that in user code:

自C89解决方案以来,在用户代码:

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

Easy enough to do using standard code as hinted by @steve jessop

使用@steve jessop提示的标准代码非常简单

offsetof(type, member-designator)

offsetof(类型、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.19 - 3

#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继续。

#14


0  

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是尺寸!!

#15


0  

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.

希望这个有帮助。

#16


-1  

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

#17


-1  

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

#18


-1  

    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运算符来计算。只需将第一行中的浮点数更改为您希望计算其大小的类型

#19


-1  

#include <stdio.h>

struct {
  int a;
  char c;
};

void main() {
  struct node*temp;
  printf("%d",(char*)(temp+1)-(char*)temp);
}

#20


-1  

# include<stdio.h>

struct node
{
  int a;
  char c;
};

void main()
{
   struct node*ptr;
   ptr=(struct node*)0;
   printf("%d",++ptr);
}