当 sizeof 的大小与实际对象大小不匹配时,一切如何工作(包括运算符 '->')?
How does everything work (including operator '->'), when sizeof's size and the actual object size don't match?
在下面的代码中,我定义了一个 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 的大小与实际对象大小不匹配时,一切如何工作(包括运算符 '->')?
But how does everything work (including operator '->'), when sizeof's size and the actual object size don't match?
很简单:不是。您对实现撒谎,因此调用了未定义的行为。
首先,你从未在内存中创建过header
对象;您只需将一段内存投入 header
对象即可。所以你有一个不指向对象的指针,但你假装它指向对象。
其次,即使您尝试在该内存中正确创建一个 header
对象(或者您正在使用 C++20 的隐式创建规则),malloc
的定义也不会要求它 return 足以 space 容纳超过您指定的字节数。由于 sizeof(header)
是 16,而您只要求 9,那么您的代码只能在 malloc 实现下工作,当您要求 9 时,该实现将为您的代码提供 16 个或更多字节(实际上这并不少见)。否则,您创建的对象占用的内存多于该指针可用的内存,这也是 UB。
逍遥法外与"working"不同。
在下面的代码中,我定义了一个 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 的大小与实际对象大小不匹配时,一切如何工作(包括运算符 '->')?
But how does everything work (including operator '->'), when sizeof's size and the actual object size don't match?
很简单:不是。您对实现撒谎,因此调用了未定义的行为。
首先,你从未在内存中创建过header
对象;您只需将一段内存投入 header
对象即可。所以你有一个不指向对象的指针,但你假装它指向对象。
其次,即使您尝试在该内存中正确创建一个 header
对象(或者您正在使用 C++20 的隐式创建规则),malloc
的定义也不会要求它 return 足以 space 容纳超过您指定的字节数。由于 sizeof(header)
是 16,而您只要求 9,那么您的代码只能在 malloc 实现下工作,当您要求 9 时,该实现将为您的代码提供 16 个或更多字节(实际上这并不少见)。否则,您创建的对象占用的内存多于该指针可用的内存,这也是 UB。
逍遥法外与"working"不同。