改变类大小的向量
编辑:
尽管格式错误,但这个问题有一个很好的收获。因此,我正在编辑此问题,以便以更好的格式保留此问题,以供将来偶然发现此问题的访问者使用。
在下面的代码示例中,有人可以解释为什么在 memcpy
之后类的大小与预期不同吗?原因是什么?
这里是 Ideone 上的在线演示。
#include<iostream>
#include<vector>
#include<cstdio>
#include<cstring>
using namespace std;
class A
{
public:
int a;
virtual void f1() { cout <<"inside a::f1\n"; }
A() { a = 1; }
};
class B
{
public:
int b;
virtual void f2() { cout <<"inside b::f2\n"; }
virtual void f5() { cout <<"inside b::f5\n"; }
B() { b = 2; }
};
class C : public A, public B
{
public:
int c;
void f1() { cout <<"inside c::f1\n"; }
void f2() { cout <<"inside c::f2\n"; }
virtual void f3() { cout <<"inside c::f3\n"; }
virtual void f4() { cout <<"inside c::f4\n"; }
C() { c = 3; }
};
int fun()
{
int a = 1;
return a * 2;
}
int main()
{
C c;
C c2;
int (*g)() = &fun;
void (A::*g1)() = &A::f1;
void (C::*g2)();
g2 = &C::f1;
(c.*g2)();
printf("%p\n",g2);
cout << sizeof(g2) << endl;
g2 = &C::f2;
(c.*g2)();
printf("%p\n", g2);
// Why is the output 1 here in g++ or visual C++?
cout << g2;
// Why is the sizeof returning 8? Please explain.
cout << sizeof(g2) << endl;
g2 = &C::f1;
std::vector<unsigned char> a_vec(sizeof(g2));
memcpy(&a_vec[0], &g2, sizeof(g2));
for(size_t i = 0; i < sizeof(g2); ++i)
{
cout << hex << static_cast<unsigned>(a_vec[i]) << " ";
}
cout << endl;
g2 = &C::f2;
std::vector<unsigned char> a_vec1(sizeof(g2));
memcpy(&a_vec1[0], &g2, sizeof(g2));
for(size_t i = 0; i < sizeof(g2); ++i)
{
cout << hex << static_cast<unsigned>(a_vec1[i]) << " ";
}
cout << endl;
cout << sizeof(g) <<endl;
cout << sizeof(g1) <<endl;
cout << sizeof(g2) <<endl;
// Why is sizeof(C) printing 14 and not 20 in visual C++?
// If yes why is this so ?
cout << sizeof(C) << endl;
cout << sizeof(c2) << endl;
cout << (&c) << endl;
cout << c.a << endl;
cout << c.b << endl;
cout << c.c << endl;
return 0;
}
从上面的代码示例中,我得到的输出是:
inside c::f1
0x1
8
inside c::f2
0x5
18
1 0 0 0 0 0 0 0
5 0 0 0 0 0 0 0
4
8
8
14
14
0xbffe375c
1
2
3
以下是我的问题:
为什么这里的输出
<块引用>1
是在 g++ 或 Visual C++ 中?cout << g2;
为什么
<块引用>sizeof
返回8
?请解释一下。cout <<大小(g2) <<结束;
为什么在 Visual C++ 中
<块引用>sizeof(C)
打印14
而不是20
?如果是,为什么会这样?cout <<大小(C) <<结束;
EDIT:
Though badly formatted this Question had a nice catch.So, I am editing this to retain this in a better format for future visitors who stumble across this question.
In the code sample below can someone please explain Why is the size of class different than expected after memcpy
? What is the reason?
Here is the online demo on Ideone.
#include<iostream>
#include<vector>
#include<cstdio>
#include<cstring>
using namespace std;
class A
{
public:
int a;
virtual void f1() { cout <<"inside a::f1\n"; }
A() { a = 1; }
};
class B
{
public:
int b;
virtual void f2() { cout <<"inside b::f2\n"; }
virtual void f5() { cout <<"inside b::f5\n"; }
B() { b = 2; }
};
class C : public A, public B
{
public:
int c;
void f1() { cout <<"inside c::f1\n"; }
void f2() { cout <<"inside c::f2\n"; }
virtual void f3() { cout <<"inside c::f3\n"; }
virtual void f4() { cout <<"inside c::f4\n"; }
C() { c = 3; }
};
int fun()
{
int a = 1;
return a * 2;
}
int main()
{
C c;
C c2;
int (*g)() = &fun;
void (A::*g1)() = &A::f1;
void (C::*g2)();
g2 = &C::f1;
(c.*g2)();
printf("%p\n",g2);
cout << sizeof(g2) << endl;
g2 = &C::f2;
(c.*g2)();
printf("%p\n", g2);
// Why is the output 1 here in g++ or visual C++?
cout << g2;
// Why is the sizeof returning 8? Please explain.
cout << sizeof(g2) << endl;
g2 = &C::f1;
std::vector<unsigned char> a_vec(sizeof(g2));
memcpy(&a_vec[0], &g2, sizeof(g2));
for(size_t i = 0; i < sizeof(g2); ++i)
{
cout << hex << static_cast<unsigned>(a_vec[i]) << " ";
}
cout << endl;
g2 = &C::f2;
std::vector<unsigned char> a_vec1(sizeof(g2));
memcpy(&a_vec1[0], &g2, sizeof(g2));
for(size_t i = 0; i < sizeof(g2); ++i)
{
cout << hex << static_cast<unsigned>(a_vec1[i]) << " ";
}
cout << endl;
cout << sizeof(g) <<endl;
cout << sizeof(g1) <<endl;
cout << sizeof(g2) <<endl;
// Why is sizeof(C) printing 14 and not 20 in visual C++?
// If yes why is this so ?
cout << sizeof(C) << endl;
cout << sizeof(c2) << endl;
cout << (&c) << endl;
cout << c.a << endl;
cout << c.b << endl;
cout << c.c << endl;
return 0;
}
From the above code sample the Output I get is:
inside c::f1
0x1
8
inside c::f2
0x5
18
1 0 0 0 0 0 0 0
5 0 0 0 0 0 0 0
4
8
8
14
14
0xbffe375c
1
2
3
Following are my Questions:
Why is the output
1
here in g++ or visual C++?cout << g2;
Why is the
sizeof
returning8
? Please explain.cout << sizeof(g2) << endl;
Why is
sizeof(C)
printing14
and not20
in visual C++? If yes why is this so?cout << sizeof(C) << endl;
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
为什么
sizeof
返回8
。请解释一下?返回 8,因为
g2
是一个指针,而您的环境中指针的大小是 8。为什么在 g++ 中输出
1
还是 Visual C++?<<运算符
没有接受指针的重载版本。因此,指针被转换为 bool 类型,值为 1,并且cout
打印它。C++ 标准允许这样做:
C++03 标准 4.12 布尔转换
为什么在 Visual C++ 中
sizeof(C)
打印14
而不是20
。它显示
的大小>C
正确地只是十六进制(十六进制的 14
==十进制的 20
)。这是因为您之前使用了hex
I/O 操纵器来打印地址。将再次将 I/O 操纵器设置为十进制模式,并且将按照您的预期输出
20
。关于 printf 和类型安全的一句话:
printf
不是类型安全的。使用printf
时,这是用户的责任将正确的格式描述符和数据类型传递给它。如果不匹配,则会出现未定义行为。未定义的行为意味着程序可能会崩溃或显示任何奇怪的行为。是未定义行为的一个示例,格式描述符和数据类型不匹配。请注意,编译器确实会抱怨这一点,您应该始终留意并检查编译器发出的此类警告。
Why is the
sizeof
returning8
. Please explain?returns 8 because
g2
is a pointer and size of an pointer on your enviornment is 8.Why is the output
1
here in g++ or visual C++?The
<< operator
does not have an overloaded version which accepts a pointer. So the pointer gets converted to a bool type, with a value 1, andcout
prints it.The C++ Standard allows this:
C++03 Standard 4.12 Boolean conversions
Why is
sizeof(C)
printing14
and not20
in visual C++.It displays the size of
C
correctly just in hexadecimal(14 in hex
==20 in decimal
). This is because you used thehex
I/O manippulator to print an address before.will set the I/O manipulator to decimal mode again and it will output
20
as you expect.A word about
printf
and type safety:printf
is not type safe.When usingprintf
it is the users responsibility to pass the proper formart descriptor and data type to it. If there is a mismatch then an Undefined Behavior will occur. An Undefined behavior means that the program might crash or show any weird behavior.Is an example of Undefined Behavior, there is a mismatch in the format descriptor and the data type. Note that the compiler does complain about this and you should always look out and check such warnings emitted by the compiler.
给定类型的
sizeof
结果永远不会改变。 (至少对于一个符合 C++ 程序。我相信 g++ 支持 C++ 中的 VLA,作为
扩展名,并且包含 VLA 的对象的
size
可能会发生变化。)关于您的明确问题:
是未定义的行为。您将指向成员的指针传递给输出
需要
void*
的格式化程序。 (g++ 会对此发出警告,我相信,至少有某些选择。)你可能会得到
任何事情(包括程序崩溃)。指向成员的指针不是
void*
,且无法转换为void*
。我不敢相信这能编译。
sizeof(g2)
返回 8,因为这是指向成员的指针的大小在您的系统上。
打印 14,因为这是该类型对象的十六进制大小
您系统上的
C
。换句话说,sizeof(C)
是 20。因为您已经将输出设置为
hex
,并且永远不要重置它,输出是十六进制的。The results of
sizeof
for a given type never change. (At least for aconforming C++ program. g++, I believe, supports VLAs in C++, as an
extension, and the
sizeof
an object containing a VLA might change.)With regards to your explicit questions:
is undefined behavior. You're passing a pointer to member to an output
formatter which requires a
void*
. (g++ will warn about this, Ibelieve, at least with certain options.) You might get just about
anything (including a program crash). Pointers to members are not
void*
, and can't be converted tovoid*
.I can't believe that this compiles.
sizeof(g2)
returns 8 because this is the size of a pointer to memberon your system.
Prints 14 because this is the size in hexadecimal of an object of type
C
on your system. In other words,sizeof(C)
is 20. Since you'veset output for
hex
, and never reset it, the output is hexadecimal.