如何确定结构成员的大小?

How can i identify the size of structure member?

struct busData{
int busNum;
char str[SIZE+1]; //SIZE  = 1000
};

int main(){
    struct busData *bus = (struct busData*)calloc(5, sizeof(struct busData));


printf("\n%d", sizeof(bus)); //result is 4
free(bus);    
return 0;
    }

现在它显示“4”或“8”,具体取决于平台。我认为它应该显示 5040 对吗?因为我用calloc()给了5值。那么我怎样才能得到5040呢?我一直在使用这 3 个元素,直到 'bus+2' 然后我用 free(bus) 释放了出来;我想知道剩下多少元素(它应该显示 2008)。所以我需要5040?

Now It is showing '4' as a result. I think it should display 5040 right?

不,你错了。检查数据类型。

首先,关于 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. [...]

bus是一个指针,所以,sizeof(bus)sizeof (struct busData*)一样,都是指针的大小,根据你的环境,可以给你结果, 其中, 常见的无为 4 或 8.

在那之后,结构元素之间和末尾可以有填充,所以结构定义为

struct busData{
int busNum;
char str[SIZE+1]; //SIZE  = 1000
};
对于大多数环境,

定义该类型的变量并尝试通过 sizeof 检查大小可能不会 给你 (4+1000+1) == 1005 字节。

再次引用,

[....] When applied to an operand that has structure or union type, the result is the total number of bytes in such an object, including internal and trailing padding.

因此,您还需要考虑填充。

也就是说,

   printf("\n%d", sizeof(bus));

实际上导致 undefined behavior。你需要写

 printf("\n%zu", sizeof(bus));

as sizeof 产生 size_t.

类型的结果
sizeof(bus)

这里bus是一个指针所以sizeof()将return4这是你使用的平台中指针的大小。(取决于使用的平台).
如果您想知道结构的大小,请使用 sizeof(struct busData)sizeof(*bus)

您正在尝试输出指针的大小bus,而不是指针指向的 5 个对象。

试试下面的演示程序

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

#define SIZE    1000

struct busData
{
    int busNum;
    char str[SIZE+1]; //SIZE  = 1000
};

int main(void) 
{
    struct busData *bus = (struct busData*)calloc(5, sizeof(struct busData));
    printf("\n%zu\n", 5 * sizeof( *bus ) );

    return 0;
}

程序输出为

5040

注意转换说明符和用作 printf 调用参数的表达式

    printf("\n%zu\n", 5 * sizeof( *bus ) );
               ^^     ^^^^^^^^^^^^^^^^^

请注意,无论指针是指向单个对象还是指向对象数组的第一个对象,指针都不会提供信息。所以使用指针bus你必须明确指定指针指向多少对象。

执行以下语句可以获得相同的结果

printf("\n%zu\n", sizeof( struct busData[5] ) );

How can i identify the size of structure member?

使用指向动态分配内存的指针,无法知道指针指向的内存大小。

如果您需要知道 malloc/calloc 之后的大小,您只需 "remember" 您 malloc/calloc 编辑了多少,即将其保存在变量中。

您可以将它包装在另一个结构中并提供一个 create 函数。类似于:

struct busData{
    int busNum;
    char str[SIZE+1]; //SIZE  = 1000
};

struct busDataContainer{
    size_t size;
    struct busData* busData;
};

struct busDataContainer createBusData(size_t n)
{
    struct busDataContainer c;
    c.size = n * sizeof(struct busData);
    c.busData = calloc(n, sizeof(struct busData));
    return c;
}

int main(){
    struct busDataContainer bus = createBusData(5);
    printf("\n%zu", bus.size;
    return 0;
}

我认为代码从一开始就搞砸了。 sizeof 的问题已经在其他答案中解释过了。

另一个大问题是:

Because I gave 5 value with calloc(). So how can I get 5040? i am using the 3 elements until 'bus+2' and then I am freeing up with free(bus); And i want to know how many elements left (it should show 2008). so i need 5040?

听起来您想在调用 free 后使用剩余的 2 个元素。

第一个:

你有 1 个指针。编译器可以告诉你指针的大小和指针指向的单个元素的大小。 编译器不知道您为该类型的 1 个以上元素分配了内存,因此无法告诉您指针大小或 1 个元素大小以外的任何信息。

第二个:

没有像"using"这样的概念有些记忆。对于编译器和 OS 是否向内存位置写入内容并不重要。它不关心某些字节是否仍然(或再次)填充 0.

第三名:

如果您分配一块内存并再次释放它,整个 块将被释放并且不能再使用。如果您期望仍然可以使用 2008 个字节,那您就错了!调用 free 后,您的指针将指向无效地址。之后使用该指针访问内存是未定义的行为