当 sizeof 的大小与实际对象大小不匹配时,一切如何工作(包括运算符'->')?

Posted

技术标签:

【中文标题】当 sizeof 的大小与实际对象大小不匹配时,一切如何工作(包括运算符\'->\')?【英文标题】:How does everything work (including operator '->'), when sizeof's size and the actual object size don't match?当 sizeof 的大小与实际对象大小不匹配时,一切如何工作(包括运算符'->')? 【发布时间】:2020-04-16 05:16:57 【问题描述】:

在下面的代码中,我定义了一个 9 字节的结构 header,它的大小为 16 字节。 然后我从堆中动态分配 9 个字节并将其分配给 header 指针。

struct header                 

     uint8_t chunk_id;               
     long int format;                 
;

int main()
   
    std::cout << "sizeof(header) " << sizeof(header) << '\n';

    auto head = (header*)malloc(9);
    head->chunk_id =3;
    head->format=5;    
    std::cout << (int)head->chunk_id << " " << head->format << '\n' << sizeof(*head);

    free(head);
    return 0;

输出:

sizeof(header) 16
3 5
16

事实证明,sizeof 仍然通知这个对象是 16 个字节(虽然是 9 个字节)。我想它只是看结构的定义。 但是当 sizeof 的大小和实际对象大小不匹配时,一切如何工作(包括运算符'->')?

【问题讨论】:

sizeof 是一个编译时常量。它对您在运行时将要做什么一无所知。其次,您的代码具有未定义的行为,因为您只为实际大小为 16 字节的内容分配了 9 个字节。 这能回答你的问题吗? Why isn't sizeof for a struct equal to the sum of sizeof of each member? 【参考方案1】:

但是当 sizeof 的大小和实际对象大小不匹配时,一切如何工作(包括运算符'->')?

简单:它没有。你对实现撒了谎,因此你调用了未定义的行为。

首先,您从未在内存中创建过header 对象;您只需将一块内存投射到该header 对象中。所以你有一个不指向对象的指针,但你假装它指向。

其次,即使您尝试在该内存中正确创建 header 对象(或者您正在使用 C++20 的隐式创建规则),malloc 的定义并不要求它返回足够的空间保存超过您指定的字节数。由于sizeof(header) 是 16,而您只要求 9,那么您的代码只能在 malloc 实现下工作,当您要求 9 时,您的代码可以使用 16 个或更多字节(这实际上并不少见)。否则,您创建的对象占用的内存比通过该指针可用的内存还要多,这也是 UB。

逃避某事与“工作”不同。

【讨论】:

以上是关于当 sizeof 的大小与实际对象大小不匹配时,一切如何工作(包括运算符'->')?的主要内容,如果未能解决你的问题,请参考以下文章

sizeof和strlen的区别

sizeof和strlen

sizeof和strlen

strlen()函数和sizeof算符

Sizeof与Strlen的区别与联系

navigationBar.IntrinsicContentSize.height 与实际栏的大小不匹配