admin管理员组文章数量:1435498
#include <bits/stdc++.h>
using namespace std;
class Trie{
int a;
Trie * child[26];
};
class Trie2{
int a;
char b;
Trie * child[26];
};
int main()
{
cout<<sizeof(Trie)<<endl;
cout<<sizeof(Trie2)<<endl;
return 0;
}
Both classes output as 216 bytes. I could understand for the first type Trie
(4 (for integers) + 4 (for padding) + 26 x 8), but I can't understand for the second type Trie2
.
I ran the code, and was expecting different results.
#include <bits/stdc++.h>
using namespace std;
class Trie{
int a;
Trie * child[26];
};
class Trie2{
int a;
char b;
Trie * child[26];
};
int main()
{
cout<<sizeof(Trie)<<endl;
cout<<sizeof(Trie2)<<endl;
return 0;
}
Both classes output as 216 bytes. I could understand for the first type Trie
(4 (for integers) + 4 (for padding) + 26 x 8), but I can't understand for the second type Trie2
.
I ran the code, and was expecting different results.
Share Improve this question edited Nov 17, 2024 at 1:57 Remy Lebeau 602k36 gold badges508 silver badges853 bronze badges asked Nov 16, 2024 at 21:30 user762007user762007 151 silver badge1 bronze badge 5- 3 What size would you have expected for the second and why? – Patrick Roberts Commented Nov 16, 2024 at 21:33
- 2 On a side note: Why should I not #include <bits/stdc++.h>? – Remy Lebeau Commented Nov 17, 2024 at 1:58
- 1 also check What's the problem with "using namespace std;"? – phuclv Commented Nov 17, 2024 at 2:50
- What do you know about memory alignment and padding? – Pepijn Kramer Commented Nov 17, 2024 at 5:28
- This question is similar to: Why isn't sizeof for a struct equal to the sum of sizeof of each member?. If you believe it’s different, please edit the question, make it clear how it’s different and/or how the answers on that question are not helpful for your problem. – BoP Commented Nov 17, 2024 at 9:19
4 Answers
Reset to default 2This is due to the alignment. The pointer array is aligned on pointer boundaries. This is implementation dependent, but in your case probably 64 bits. In your implementation, the size of an int
seems to be smaller than the difference between two aligned addresses for pointers. So the extra byte for char
does not make any difference.
Try making a
an int*
or a long
(again, all this is implementation dependent), and you'll probably see that the extra char will this time matter. Also due to alignment matters, the difference will not necessarily be 1.
Online demo.
You can easily discover the size of a type, and also its alignment requirements used by your compiler:
cout<<sizeof(Trie*)<<","<<alignof(Trie*)<<endl;
cout<<sizeof(int)<<","<<alignof(int)<<endl;
cout<<sizeof(int*)<<","<<alignof(int*)<<endl;
cout<<sizeof(char)<<","<< alignof(char)<<endl;
alignof 8 means that the address of an object of the type must be a multiple of the alignment factor.
I assume you are talking about 64-bit machine, since you said "26 x 8". Here's how a typical 64-bit machine sees your structs:
struct Trie {
[4 bytes] a;
[4 bytes] padding;
[26x8 bytes] child;
};
struct Trie2 {
[4 bytes] a;
[1 byte] b;
[3 bytes] padding;
[26x8 bytes] child;
};
Which follows from the fact that int takes 4 bytes, pointers are aligned to 8, and char takes 1 byte and is aligned to 1. So it fits in the padding of the previous struct.
Note that the result will be different on a 32-bit machine. Most certainly Trie2
will be bigger, because pointers will be aligned to 4 instead of 8. So there will be no padding in the first Trie
, but the second one will still need it.
This is how padding in structures/classes works on a 64 bit PC:
#include <iostream>
struct Trie {
int a;
Trie* child[26];
};
struct Trie2 {
int a;
char b;
Trie* child[26];
};
int main() {
std::cout << "Trie::a location " << offsetof(Trie, a) << " to "
<< offsetof(Trie, a) + sizeof(Trie::a) << "\n";
std::cout << "Trie::child location " << offsetof(Trie, child) << " to "
<< offsetof(Trie, child) + sizeof(Trie::child) << "\n";
std::cout << "Trie2::a location " << offsetof(Trie2, a) << " to "
<< offsetof(Trie2, a) + sizeof(Trie2::a) << "\n";
std::cout << "Trie2::b location " << offsetof(Trie2, b) << " to "
<< offsetof(Trie2, b) + sizeof(Trie2::b) << "\n";
std::cout << "Trie2::child location " << offsetof(Trie2, child) << " to "
<< offsetof(Trie2, child) + sizeof(Trie2::child) << "\n";
}
Output
Trie::a location 0 to 4
Trie::child location 8 to 216
Trie2::a location 0 to 4
Trie2::b location 4 to 5
Trie2::child location 8 to 216
As you can see, there is 4 byte gaps between a
and child
. This is due to the array alignment usually for performance. Trie2
partially fills that gap with b
. The sizeof(Trie2)
is not changed. If you make b
bigger, for example double b
, it will not fit into the gap and Trie2
will be bigger.
Both Trie
and Trie2
end up taking 216 bytes because of how memory alignment works. Even though Trie2
has an extra char
variable, the compiler adds padding after it to make sure the array of pointers (child[26]
) starts at an 8-byte boundary (which is required for pointers on a 64-bit system). This padding makes the total size of both classes the same, even though the structure of the two classes is slightly different.
本文标签: cWhy is the size of two different class objects the sameStack Overflow
版权声明:本文标题:c++ - Why is the size of two different class objects the same? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1745647542a2668226.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论