问问~
最近发现一段代码感觉很神奇,我把它简化了下
class A
{
public:
typedef struct B
{
char x;
char y;
char z;
}*PB
}
void show(char *info)
{
A::PB p=(A::PB)info;//重点是这个强制转换
p->x='x';
p->y='y';
p->z='z';
}
int main()
{
char s[100]="";
show(s);
cout<<s<<endl;//xyz 能输出xyz的原因是什么??
}
[解决办法]
s[0] = 'x';
s[1] = 'y';
s[2] = 'z';
[解决办法]
数组s先被初始化为全'\0',而后在show里将前3字节分别赋值为'x'、'y'、'z',和第4个字节上的'\0'构成字符串"xyz"。
[解决办法]
我就不多说了,直接上测试结果:
- Assembly code
[chenbing@localhost ~]$ gdb appGNU gdb (GDB) Red Hat Enterprise Linux (7.0.1-23.el5)Copyright (C) 2009 Free Software Foundation, Inc.License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>This is free software: you are free to change and redistribute it.There is NO WARRANTY, to the extent permitted by law. Type "show copying"and "show warranty" for details.This GDB was configured as "i386-redhat-linux-gnu".For bug reporting instructions, please see:<http://www.gnu.org/software/gdb/bugs/>...Reading symbols from /opt/chenbing/app...done.(gdb) l1 #include <iostream>2 using namespace std;34 int main()5 {6 char lstr[5] = "";7 return 0;8 }(gdb) b 6Breakpoint 1 at 0x8048535: file test.cpp, line 6.(gdb) rStarting program: /opt/chenbing/app Breakpoint 1, main () at test.cpp:66 char lstr[5] = "";(gdb) n7 return 0;(gdb) p lstr$1 = "\000\000\000\000"
[解决办法]
void show(char *);函数传进来的参数是一个地址,那么你对该指针指向的内存内容的修改,就是修改的函数main中的s[100]的内存。所以,在main中调用show之后,s的内存就已经被修改了。
[解决办法]
行为可控,属于可预见行为,没有任何问题.
3个char成员均在1字节对齐,毫无问题。
[解决办法]
还有一个原因是都是char都是一个字节,内存对齐,是连续存储所以才会是xyz
不过感觉写代码的人当时应该没想那么多