如何在不取消引用的情况下确定指向数据的大小?

How to determine the size of pointed-to data without dereferencing?

简而言之

在标准 C 中,如何根据指针确定指向数据的大小而不取消引用它?

更详细

我想实现标准C++98库中容器的C99仿制,如下图:

#define vector(ElemType)            \
    struct {                        \
        ElemType *data;             \
        size_t count;               \
        size_t capacity;            \
        // typedef ElemType eltype; \ // not permitted in C!
    }

/* ... */

vector(double) dv;

vector_create(&dv, 10);
vector_pushback(&dv, 35.4);
vector_destroy(&dv);

主要问题是 C 不允许 typedefstruct 中,参见 separate thread

我目前正在使用 size_t 的额外数据成员来跟踪 sizeof (ElemType)。有没有办法在不取消引用的情况下从 data 指针获取 sizeof (ElemType)

要获取类型的大小,您可以将 sizeof 应用于数据本身:

sizeof(*dv.data)

或者简单地说:

sizeof *dv.data

但我发现带括号的版本更具可读性。

指针dv.data可以是NULL,它没有被解引用,对于这个简单的例子,sizeof是在编译时计算的。

C11 6.5.3.4

The sizeof operator yields the size (in bytes) of its operand, which may be an expression or the parenthesized name of a type. The size is determined from the type of the operand. The result is an integer. If the type of the operand is a variable length array type, the operand is evaluated; otherwise, the operand is not evaluated and the result is an integer constant.

事实上,将对象大小传递给malloc是推荐的方法:

ElemType *p = malloc(sizeof(*p) * capacity);

使用 sizeof(*p) 而不是 sizeof(ElemType) 可以防止大小不匹配,如果您稍后更改 p.

的类型,则可能无法检测到大小不匹配

没有办法得到数组dv.data指向的元素个数,不单独维护计数,这就是capacity成员的目的。

在 C99 中可以使用 sizeof(*dv.data)