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

Nik*_*128 3 c++ struct memory-alignment

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

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;
}
Run Code Online (Sandbox Code Playgroud)

输出:

sizeof(header) 16
3 5
16
Run Code Online (Sandbox Code Playgroud)

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

Nic*_*las 5

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

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

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

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

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