C++ 为什么是C++;程序返回16字节?
当使用gcc编译并在32位体系结构上执行时,下面的程序返回16个字节。我想知道它为什么会返回,因为它既不使用长的双成员,也不在64位机器上运行,而且没有定义虚拟函数来获取额外的内存字节,当计算double和int数据成员的大小时,结果大约是12字节。那么为什么会有16字节的值呢C++ 为什么是C++;程序返回16字节?,c++,C++,当使用gcc编译并在32位体系结构上执行时,下面的程序返回16个字节。我想知道它为什么会返回,因为它既不使用长的双成员,也不在64位机器上运行,而且没有定义虚拟函数来获取额外的内存字节,当计算double和int数据成员的大小时,结果大约是12字节。那么为什么会有16字节的值呢 class A { public: void* data; }; void* operator new (size_t sz, A& obj) { printf("Custom operato
class A {
public:
void* data;
};
void* operator new (size_t sz, A& obj) {
printf("Custom operator new called for %d bytes\n", sz);
return obj.data;
}
class foo {
public:
double a;
int x;
foo() { printf("foo constructor called (this=%p)\n", this); }
};
int main() {
A obj;
obj.data = malloc(sizeof(foo));
printf("Allocator data: %p\n", obj.data); // Allocator data: 0x4601a8
foo *f = new (obj) foo; // Custom operator new called for **16 bytes**
// foo constructor called (this=0x4601a8)
printf("foo allocated at %p\n", f); // foo allocated at 0x4601a8
}
4
字节作为填充添加到foo
的末尾。这通常是出于对齐目的而进行的-在您的体系结构中,double
与8
字节对齐,因此如果您创建一个foo
s数组,填充字节将保证成员a
正确对齐
在类类型中,不能保证大小等于成员大小之和。通常情况下,情况并非如此
有一些特殊的编译器相关标志可以防止添加填充字节,您可以查找这些字节。(
pragma pack
)4
字节作为填充添加到foo
的末尾。这通常是出于对齐目的而进行的-在您的体系结构中,double
与8
字节对齐,因此如果您创建一个foo
s数组,填充字节将保证成员a
正确对齐
在类类型中,不能保证大小等于成员大小之和。通常情况下,情况并非如此
有一些特殊的编译器相关标志可以防止添加填充字节,您可以查找这些字节。(
pragma pack
)4
字节作为填充添加到foo
的末尾。这通常是出于对齐目的而进行的-在您的体系结构中,double
与8
字节对齐,因此如果您创建一个foo
s数组,填充字节将保证成员a
正确对齐
在类类型中,不能保证大小等于成员大小之和。通常情况下,情况并非如此
有一些特殊的编译器相关标志可以防止添加填充字节,您可以查找这些字节。(
pragma pack
)4
字节作为填充添加到foo
的末尾。这通常是出于对齐目的而进行的-在您的体系结构中,double
与8
字节对齐,因此如果您创建一个foo
s数组,填充字节将保证成员a
正确对齐
在类类型中,不能保证大小等于成员大小之和。通常情况下,情况并非如此
有一些特殊的编译器相关标志可以防止添加填充字节,您可以查找这些字节。(
pragma pack
)结构对象中可能有未命名的填充,称为
在您的例子中,double与8个字节对齐,因此foo的大小应该是8*N,因此4个字节填充在结构对象中可能有未命名的填充,称为
在您的例子中,double与8个字节对齐,因此foo的大小应该是8*N,因此4个字节填充在结构对象中可能有未命名的填充,称为
在您的例子中,double与8个字节对齐,因此foo的大小应该是8*N,因此4个字节填充在结构对象中可能有未命名的填充,称为
在您的例子中,double与8个字节对齐,因此foo的大小应该是8*N,因此在运行代码时,我发现4个字节被填充了:
class A {
public:
void* data;
};
void* operator new (size_t sz, A& obj) {
printf("Custom operator new called for %d bytes\n", sz);
return obj.data;
}
class foo {
public:
double a;
int x;
foo() { printf("foo constructor called (this=%p)\n", this); }
};
int main() {
A obj;
obj.data = malloc(sizeof(foo));
printf("Allocator data: %p\n", obj.data); // Allocator data: 0x991d008
printf("size of obj: %d\n", sizeof(obj)); // size of obj: 4
printf("size of foo: %d\n",sizeof(foo)); // size of foo: 12
foo *f = new (obj) foo; // Custom operator new called for **12 bytes**
// foo constructor called (this=0x991d008)
printf("foo allocated at %p\n", f); // foo allocated at 0x991d008
}
我添加了两个额外的打印语句,这里
foo
的大小是12。这是double
+int
当我运行您的代码时,我发现以下内容:
class A {
public:
void* data;
};
void* operator new (size_t sz, A& obj) {
printf("Custom operator new called for %d bytes\n", sz);
return obj.data;
}
class foo {
public:
double a;
int x;
foo() { printf("foo constructor called (this=%p)\n", this); }
};
int main() {
A obj;
obj.data = malloc(sizeof(foo));
printf("Allocator data: %p\n", obj.data); // Allocator data: 0x991d008
printf("size of obj: %d\n", sizeof(obj)); // size of obj: 4
printf("size of foo: %d\n",sizeof(foo)); // size of foo: 12
foo *f = new (obj) foo; // Custom operator new called for **12 bytes**
// foo constructor called (this=0x991d008)
printf("foo allocated at %p\n", f); // foo allocated at 0x991d008
}
我添加了两个额外的打印语句,这里
foo
的大小是12。这是double
+int
当我运行您的代码时,我发现以下内容:
class A {
public:
void* data;
};
void* operator new (size_t sz, A& obj) {
printf("Custom operator new called for %d bytes\n", sz);
return obj.data;
}
class foo {
public:
double a;
int x;
foo() { printf("foo constructor called (this=%p)\n", this); }
};
int main() {
A obj;
obj.data = malloc(sizeof(foo));
printf("Allocator data: %p\n", obj.data); // Allocator data: 0x991d008
printf("size of obj: %d\n", sizeof(obj)); // size of obj: 4
printf("size of foo: %d\n",sizeof(foo)); // size of foo: 12
foo *f = new (obj) foo; // Custom operator new called for **12 bytes**
// foo constructor called (this=0x991d008)
printf("foo allocated at %p\n", f); // foo allocated at 0x991d008
}
我添加了两个额外的打印语句,这里
foo
的大小是12。这是double
+int
当我运行您的代码时,我发现以下内容:
class A {
public:
void* data;
};
void* operator new (size_t sz, A& obj) {
printf("Custom operator new called for %d bytes\n", sz);
return obj.data;
}
class foo {
public:
double a;
int x;
foo() { printf("foo constructor called (this=%p)\n", this); }
};
int main() {
A obj;
obj.data = malloc(sizeof(foo));
printf("Allocator data: %p\n", obj.data); // Allocator data: 0x991d008
printf("size of obj: %d\n", sizeof(obj)); // size of obj: 4
printf("size of foo: %d\n",sizeof(foo)); // size of foo: 12
foo *f = new (obj) foo; // Custom operator new called for **12 bytes**
// foo constructor called (this=0x991d008)
printf("foo allocated at %p\n", f); // foo allocated at 0x991d008
}
我添加了两个额外的打印语句,这里
foo
的大小是12。这是因为编译器应用了内部填充。我们可以通过使用\uuuu-packed编译器指令来避免这种情况
你可以参考下面的文章来了解填充
这是因为编译器应用了内部填充。我们可以通过使用\uuuu-packed编译器指令来避免这种情况 你可以参考下面的文章来了解填充
这是因为编译器应用了内部填充。我们可以通过使用\uuuu-packed编译器指令来避免这种情况 你可以参考下面的文章来了解填充
这是因为编译器应用了内部填充。我们可以通过使用\uuuu-packed编译器指令来避免这种情况 你可以参考下面的文章来了解填充 考虑一下。编译器将对象的数据对齐,以便将它们存储在内存中,这样CPU就可以在一次加载中获取它们—这仅适用于对齐的数据。这是硬件方面。请考虑。编译器将对象的数据对齐,以便将它们存储在内存中,这样CPU就可以在一次加载中获取它们—这仅适用于对齐的数据。这是硬件方面。请考虑。编译器将对象的数据对齐,以便将它们存储在内存中,这样CPU就可以在一次加载中获取它们—这仅适用于对齐的数据。这是硬件方面。请考虑。编译器将对象的数据对齐,以便将它们存储在备忘录中