是否可以通过指针找到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
答案 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:不,不可能