是否有可能获得指针指向的项目的大小?

时间:2016-09-12 20:41:49

标签: c

是否可以通过指针找到item_t的大小?

typedef struct item
{
  char x;
  char y;
  char life;
}item_t;

void main (void)
{
  item_t test;
  void *ptr = &test;
  printf("%d\n",sizeof(ptr));
}
return: 8

3 个答案:

答案 0 :(得分:3)

如果ptr的类型为void*,则不是 - 但它可能不应该是。

您无法取消引用void*指针。您可以将其转换为其他指针类型并取消引用转换结果。这有时候很有用,但更常见的是你应该首先用正确的类型定义指针。

如果需要指向item_t对象的指针,请使用item_t*指针:

item_t test;
item_t *ptr = &test;
printf("%zu\n", sizeof(*ptr));

这将为您提供单个item_t对象的大小,因为这是ptr指向的类型。如果ptr未初始化,或者是空指针,则会得到相同的结果,因为sizeof的操作数未被评估(有一个例外,此处不适用)。如果ptr已初始化为指向item_t个对象的数组的初始元素:

ptr = malloc(42 * sizeof *ptr);

sizeof *ptr仍然只能为您提供其中一个的大小。

sizeof运算符(通常)在编译时进行评估。它仅使用编译器可用的信息。不执行运行时计算。 (例外是一个操作数,其类型是可变长度数组。)

打印size_t类型值的正确格式(例如sizeof的结果)是%zu,而不是%d

并且void main(void)应为int main(void)(除非您有充分的理由使用非标准定义 - 您几乎肯定不会这样做)。如果某本书告诉您要定义main,其返回类型为void,请获取更好的书籍;它的作者不太了解C.

答案 1 :(得分:2)

简答:不。只给出了ptr,你所拥有的只是一个地址(由WhozCraig回答)。

更长的答案:您可以通过让所有结构中的第一个字段指定其大小来实现inheritance。例如:

struct something_that_has_size
{
  size_t size;
};

struct item
{
  size_t size;
  char x;
  char y;
  char life;
};

struct item2
{
  size_t size;
  char x;
  char y;
  char z;
  char life;
};

// Somewhere in your code
...
struct item *i1 = malloc(sizeof(struct item));
i1->size = sizeof(struct item); // you are telling yourself what the size is
struct item2 *i2 = malloc(sizeof(struct item2));
i2->size = sizeof(struct item2);

// Later in your code
void *ptr = ... // get a pointer somehow
size_t size = ((struct something_that_has_size*)ptr)->size; // here is your size

但不是尺寸,你应该更好地记录struct类型 - 它比尺寸更有用。这种技术称为discriminated union

答案 2 :(得分:1)

您只能投射void指针以获取正确类型背后的内容,您无法直接取消引用它。

#include <stdio.h>
#include <stdlib.h>

typedef struct item {
  char x;
  char y;
  char life;
} item_t;

int main()
{
  item_t test;
  void *ptr = &test;
  printf("%zu %zu\n", sizeof(*(item_t *) ptr), sizeof(item_t));
  exit(EXIT_SUCCESS);;
}

但这并没有多大用处,因为你首先需要知道这种类型并且什么也没赢。

TL; DR:不,不可能