{
int a;
int b;
char c;
char d;
}a;
struct B
{
int a;
int b;
char c;
char d;
char e;
}b;
初始化a、b;
a.a=1; a.b=2; a.c=3; a.d=4;
b.a=1; b.b=2; b.c=3; b.d=4; b.e=5;
假设a结构体直接复制个b成立: b = a;
问最后b.e的值是多少?
14 个解决方案
#1
他想知道什么呢,要成立,无非添加隐式转换,或者重载=操作符啥的,想让他=多少就=多少啊。要么就是想考你内存对齐了,这两个结构体占用内存一样的。关键还要看怎么假设他成立的吧,请楼下高人解答
#2
b.e未知。
在32位系统中对齐到4字节边界的逻辑下,A中四个域都不需要对齐调整,但需要在d后面填充两个字节,以合吃族在A数组类型中,下一个元素依然从4字节边界开始,以保证两个int类型成员正好占据一个32位字。B也一样,需要在e后面填充一个字节。
这样,如果以memcpy的方式把A对象赋值给B对象,e对应的位置正好是A对象中的填充字节,填充字节会是什么数据,这一点很难确定。
在32位系统中对齐到4字节边界的逻辑下,A中四个域都不需要对齐调整,但需要在d后面填充两个字节,以合吃族在A数组类型中,下一个元素依然从4字节边界开始,以保证两个int类型成员正好占据一个32位字。B也一样,需要在e后面填充一个字节。
这样,如果以memcpy的方式把A对象赋值给B对象,e对应的位置正好是A对象中的填充字节,填充字节会是什么数据,这一点很难确定。
#3
安在内存对齐补0的话,答案应该是0,但是那人批了我一顿。所以纠结了。
#4
一开始我也是这么想的但是那面试官说有一个确切的值得,所以就又迷茫。
还是我真的不懂啊
#5
我是不是被面试官忽悠了。
#6
假设a结构体直接复制个b成立
……这个假设怎么成立的。
……这个假设怎么成立的。
#7
b.e应该不变吧。
貌似考直接将基类对象直接赋值给派生类对象。
貌似考直接将基类对象直接赋值给派生类对象。
#8
你应该理解面试官总会想出一些牛逼的问题
#9
我怎么也觉得应该是0啊……还写了个程序看了下:
断点打在第24行,停下来以后看内存是这个样子的:
00401321 call 0x4133f0 <__main>
00401326 movl $0x1,0x474008(a.x------4B)
00401330 movl $0x2,0x47400c(a.y------4B)
0040133A movb $0x3,0x474010(a.z------1B)
00401341 movb $0x4,0x474011(a.w------1B)
00401348 movl $0x1,0x474014(b.x------4B)
00401352 movl $0x2,0x474018(b.y------4B)
0040135C movb $0x3,0x47401c(b.z------1B)
00401363 movb $0x4,0x47401d(b.w------1B)
0040136A movb $0x5,0x47401e(b.e------1B)
00401371 movl $0xc,0x18(%esp)
00401379 movl $0xc,0x1c(%esp)
并且在win32平台下a和b的大小都是12B,a填充了两个字节:0x474012和0x474013位置,b填充一个字节:0x47401f,那么如果可以做复制操作的话,并假定这个复制是简单的内存块复制,这样应该是将a所占的内存空间覆盖到b的内存空间,从而b.e位置是0x474012的内容,
可以看到a的两个填充字节都是填充0的,所以b.e也应该变成0啊……果然我也要被面试官鄙视了么。
但是这个复制的假定并不知道到底是怎么样实现的,而且不同的平台是不是也不一定就填充0,但这样的话就不会说是有确定的值了……想不明白,同求大神解惑!
#include <iostream>
using namespace std;
struct A{
int x;
int y;
char z;
char w;
}a;
struct B{
int x;
int y;
char z;
char w;
char e;
}b;
int main()
{
a.x = 1;a.y = 2;a.z = 3;a.w = 4;
b.x = 1;b.y = 2;b.z = 3;b.w = 4;b.e = 5;
int sizeA = sizeof(a);
int sizeB = sizeof(b);
cout << sizeA << endl;
cout << sizeB << endl;
return 0;
}
断点打在第24行,停下来以后看内存是这个样子的:
00401321 call 0x4133f0 <__main>
00401326 movl $0x1,0x474008(a.x------4B)
00401330 movl $0x2,0x47400c(a.y------4B)
0040133A movb $0x3,0x474010(a.z------1B)
00401341 movb $0x4,0x474011(a.w------1B)
00401348 movl $0x1,0x474014(b.x------4B)
00401352 movl $0x2,0x474018(b.y------4B)
0040135C movb $0x3,0x47401c(b.z------1B)
00401363 movb $0x4,0x47401d(b.w------1B)
0040136A movb $0x5,0x47401e(b.e------1B)
00401371 movl $0xc,0x18(%esp)
00401379 movl $0xc,0x1c(%esp)
并且在win32平台下a和b的大小都是12B,a填充了两个字节:0x474012和0x474013位置,b填充一个字节:0x47401f,那么如果可以做复制操作的话,并假定这个复制是简单的内存块复制,这样应该是将a所占的内存空间覆盖到b的内存空间,从而b.e位置是0x474012的内容,
0x474012: 00 00 01 00 00 00 02 00|00 00 03 04 05 00 00 00 ................
0x474022: 00 00 00 00 00 00 00 00|00 00 00 00 00 00 00 00 ................
可以看到a的两个填充字节都是填充0的,所以b.e也应该变成0啊……果然我也要被面试官鄙视了么。
但是这个复制的假定并不知道到底是怎么样实现的,而且不同的平台是不是也不一定就填充0,但这样的话就不会说是有确定的值了……想不明白,同求大神解惑!
#10
填充值不一定是0
面试官2b不解释
面试官2b不解释
#11
能转换么,俩不同对象,你的值是无法确定的
#12
没啥意义的假设
#13
#include <stdio.h>
struct A {
int a;
int b;
char c;
char d;
} a;
struct B {
int a;
int b;
char c;
char d;
char e;
} b;
int main() {
a.a=1; a.b=2; a.c=3; a.d=4;
b.a=1; b.b=2; b.c=3; b.d=4; b.e=5;
b = *(struct B *)&a;
printf("b.e==%d\n",b.e);
return 0;
}
//b.e==0
//
#14
如果a是全局变量,那么b.e=0
如果a是局部变量,那么b.e是未知的(a对齐的那两个字节没有被初始化)
如果a是局部变量,那么b.e是未知的(a对齐的那两个字节没有被初始化)
#1
他想知道什么呢,要成立,无非添加隐式转换,或者重载=操作符啥的,想让他=多少就=多少啊。要么就是想考你内存对齐了,这两个结构体占用内存一样的。关键还要看怎么假设他成立的吧,请楼下高人解答
#2
b.e未知。
在32位系统中对齐到4字节边界的逻辑下,A中四个域都不需要对齐调整,但需要在d后面填充两个字节,以合吃族在A数组类型中,下一个元素依然从4字节边界开始,以保证两个int类型成员正好占据一个32位字。B也一样,需要在e后面填充一个字节。
这样,如果以memcpy的方式把A对象赋值给B对象,e对应的位置正好是A对象中的填充字节,填充字节会是什么数据,这一点很难确定。
在32位系统中对齐到4字节边界的逻辑下,A中四个域都不需要对齐调整,但需要在d后面填充两个字节,以合吃族在A数组类型中,下一个元素依然从4字节边界开始,以保证两个int类型成员正好占据一个32位字。B也一样,需要在e后面填充一个字节。
这样,如果以memcpy的方式把A对象赋值给B对象,e对应的位置正好是A对象中的填充字节,填充字节会是什么数据,这一点很难确定。
#3
安在内存对齐补0的话,答案应该是0,但是那人批了我一顿。所以纠结了。
#4
一开始我也是这么想的但是那面试官说有一个确切的值得,所以就又迷茫。
还是我真的不懂啊
#5
我是不是被面试官忽悠了。
#6
假设a结构体直接复制个b成立
……这个假设怎么成立的。
……这个假设怎么成立的。
#7
b.e应该不变吧。
貌似考直接将基类对象直接赋值给派生类对象。
貌似考直接将基类对象直接赋值给派生类对象。
#8
你应该理解面试官总会想出一些牛逼的问题
#9
我怎么也觉得应该是0啊……还写了个程序看了下:
断点打在第24行,停下来以后看内存是这个样子的:
00401321 call 0x4133f0 <__main>
00401326 movl $0x1,0x474008(a.x------4B)
00401330 movl $0x2,0x47400c(a.y------4B)
0040133A movb $0x3,0x474010(a.z------1B)
00401341 movb $0x4,0x474011(a.w------1B)
00401348 movl $0x1,0x474014(b.x------4B)
00401352 movl $0x2,0x474018(b.y------4B)
0040135C movb $0x3,0x47401c(b.z------1B)
00401363 movb $0x4,0x47401d(b.w------1B)
0040136A movb $0x5,0x47401e(b.e------1B)
00401371 movl $0xc,0x18(%esp)
00401379 movl $0xc,0x1c(%esp)
并且在win32平台下a和b的大小都是12B,a填充了两个字节:0x474012和0x474013位置,b填充一个字节:0x47401f,那么如果可以做复制操作的话,并假定这个复制是简单的内存块复制,这样应该是将a所占的内存空间覆盖到b的内存空间,从而b.e位置是0x474012的内容,
可以看到a的两个填充字节都是填充0的,所以b.e也应该变成0啊……果然我也要被面试官鄙视了么。
但是这个复制的假定并不知道到底是怎么样实现的,而且不同的平台是不是也不一定就填充0,但这样的话就不会说是有确定的值了……想不明白,同求大神解惑!
#include <iostream>
using namespace std;
struct A{
int x;
int y;
char z;
char w;
}a;
struct B{
int x;
int y;
char z;
char w;
char e;
}b;
int main()
{
a.x = 1;a.y = 2;a.z = 3;a.w = 4;
b.x = 1;b.y = 2;b.z = 3;b.w = 4;b.e = 5;
int sizeA = sizeof(a);
int sizeB = sizeof(b);
cout << sizeA << endl;
cout << sizeB << endl;
return 0;
}
断点打在第24行,停下来以后看内存是这个样子的:
00401321 call 0x4133f0 <__main>
00401326 movl $0x1,0x474008(a.x------4B)
00401330 movl $0x2,0x47400c(a.y------4B)
0040133A movb $0x3,0x474010(a.z------1B)
00401341 movb $0x4,0x474011(a.w------1B)
00401348 movl $0x1,0x474014(b.x------4B)
00401352 movl $0x2,0x474018(b.y------4B)
0040135C movb $0x3,0x47401c(b.z------1B)
00401363 movb $0x4,0x47401d(b.w------1B)
0040136A movb $0x5,0x47401e(b.e------1B)
00401371 movl $0xc,0x18(%esp)
00401379 movl $0xc,0x1c(%esp)
并且在win32平台下a和b的大小都是12B,a填充了两个字节:0x474012和0x474013位置,b填充一个字节:0x47401f,那么如果可以做复制操作的话,并假定这个复制是简单的内存块复制,这样应该是将a所占的内存空间覆盖到b的内存空间,从而b.e位置是0x474012的内容,
0x474012: 00 00 01 00 00 00 02 00|00 00 03 04 05 00 00 00 ................
0x474022: 00 00 00 00 00 00 00 00|00 00 00 00 00 00 00 00 ................
可以看到a的两个填充字节都是填充0的,所以b.e也应该变成0啊……果然我也要被面试官鄙视了么。
但是这个复制的假定并不知道到底是怎么样实现的,而且不同的平台是不是也不一定就填充0,但这样的话就不会说是有确定的值了……想不明白,同求大神解惑!
#10
填充值不一定是0
面试官2b不解释
面试官2b不解释
#11
能转换么,俩不同对象,你的值是无法确定的
#12
没啥意义的假设
#13
#include <stdio.h>
struct A {
int a;
int b;
char c;
char d;
} a;
struct B {
int a;
int b;
char c;
char d;
char e;
} b;
int main() {
a.a=1; a.b=2; a.c=3; a.d=4;
b.a=1; b.b=2; b.c=3; b.d=4; b.e=5;
b = *(struct B *)&a;
printf("b.e==%d\n",b.e);
return 0;
}
//b.e==0
//
#14
如果a是全局变量,那么b.e=0
如果a是局部变量,那么b.e是未知的(a对齐的那两个字节没有被初始化)
如果a是局部变量,那么b.e是未知的(a对齐的那两个字节没有被初始化)