结构体中定义未明长度数组的有关问题-C++
结构体中定义未明长度数组的问题-C++
代码如下:
请问为什么两个sizeof返回的值都是1?,char p[]是属于什么类型的,指针?字符?
感觉两种解释都不怎么合理呀?而且如果char p[]变成char* p;的话系统是会中断的,好像是因为"wang"放在常量区。求大牛解释啊。
------最佳解决方案--------------------
char a[2]; // 毫无疑问是个数组,两个元素
a 表示该数组首元素地址,该地址存放首元素,在你的例子("wang"),应该是字符 'w'
第二个字符,则是 'a'。其它字符越界了
cnode 类之含 char a[2]; 则sizeof 就是2
如果你换成char *p; 那么 sizeof 是4,因为指针占4字节,用于保存一个地址。在你的例子里,你无法知道该地址在哪里。如果具体地,是VS的默认DEBUG的话,由于栈填充为0xCCCCCCCC,p就指向0xCCCCCCCC,因为该地址用户不可访问,所以必错无疑
------其他解决方案--------------------
我觉得这里涉及了3个问题:
1.char p[]到底是几个元素的数组.
编译以上代码的时候,我的编译器发出C4200的警告.
搜索C4200
http://msdn.microsoft.com/en-us/library/79wf64bc.aspx
从上面错误反馈可以得知,p是一个长度为0的数组,也就是p是空的,不占任何空间
2.既然p不占任何空间,为什么sizeof( cnode )为1 ?
参考<<effecitve c++ 3rd>>,第39条 [use private inheritance judiciously]中的一句话
"an Empty data member requires memory. With most compilers, sizeof(Empty) is 1, because C++'s edict against zero-size freestanding objects is typically satisfied by the silent insertion of a char into "empty" objects."
大致就是大多数编译器对待独立的空数据对象时,通常会插入一个char,所以sizeof(char)是1
3.既然cnode大小为1,为什么可以修改p[3]的值?
在我的平台上,甚至可以修改p[30]的值.微软编译器可能不怎么阻止溢出,所以能否访问p[n]的值完全是操作平台的责任,因为在我的平台上,p[30]仍然是栈空间的一部分,所以操作系统允许我修改p[30]的值,当修改p[3000]的时候,数据已经不再是我的程序划分到空间,所以系统中断了程序.
------其他解决方案--------------------
char p[];//字符数组,大小编译器确定,你说sizeof(cnode)为1那么它相当于char p[1];
至于xyz的大小肯定跟sizeof(cnode)一样。
再者,cnode(char pt[]){strcpy(p,pt);}是不安全的,strcpy是不管你p后面有多少合法的内存的。
------其他解决方案--------------------
1.char p[]肯定是char的数组类型.
2.为什么char p[]不会中断,而char* p会中断?
调试了下,发现p[]的地址和cnode对象地址都是一样的,栈上面的地址,所以赋值没有太大问题,尽管你已经溢出,处于未定义行为的状态中.操作系统允许你操作栈上的内存,毕竟这个内存块是你的程序通过提交合法分配到的.
而char* p,p因为你没初始化,p可能是很遥远的乱码地址,只要这个地址不是你的程序向操作系统成功提交的后得到的有访问权的地址,任何读写p操作系统都会中断你的程序.
------其他解决方案--------------------
自己google 柔性数组成员。
------其他解决方案--------------------
代码如下:
#include<iostream>
using namespace std;
struct cnode
{
cnode(){}
cnode(char pt[]){strcpy(p,pt);}
char p[];
};
int main(void)
{
cnode xyx("wang");
cout<<sizeof(xyx)<<" "<<sizeof(cnode)<<endl;
xyx.p[3]='4';
cout<<xyx.p<<endl;
return(0);
}
请问为什么两个sizeof返回的值都是1?,char p[]是属于什么类型的,指针?字符?
感觉两种解释都不怎么合理呀?而且如果char p[]变成char* p;的话系统是会中断的,好像是因为"wang"放在常量区。求大牛解释啊。
------最佳解决方案--------------------
char a[2]; // 毫无疑问是个数组,两个元素
a 表示该数组首元素地址,该地址存放首元素,在你的例子("wang"),应该是字符 'w'
第二个字符,则是 'a'。其它字符越界了
cnode 类之含 char a[2]; 则sizeof 就是2
如果你换成char *p; 那么 sizeof 是4,因为指针占4字节,用于保存一个地址。在你的例子里,你无法知道该地址在哪里。如果具体地,是VS的默认DEBUG的话,由于栈填充为0xCCCCCCCC,p就指向0xCCCCCCCC,因为该地址用户不可访问,所以必错无疑
------其他解决方案--------------------
我觉得这里涉及了3个问题:
1.char p[]到底是几个元素的数组.
编译以上代码的时候,我的编译器发出C4200的警告.
搜索C4200
http://msdn.microsoft.com/en-us/library/79wf64bc.aspx
从上面错误反馈可以得知,p是一个长度为0的数组,也就是p是空的,不占任何空间
2.既然p不占任何空间,为什么sizeof( cnode )为1 ?
参考<<effecitve c++ 3rd>>,第39条 [use private inheritance judiciously]中的一句话
"an Empty data member requires memory. With most compilers, sizeof(Empty) is 1, because C++'s edict against zero-size freestanding objects is typically satisfied by the silent insertion of a char into "empty" objects."
大致就是大多数编译器对待独立的空数据对象时,通常会插入一个char,所以sizeof(char)是1
3.既然cnode大小为1,为什么可以修改p[3]的值?
在我的平台上,甚至可以修改p[30]的值.微软编译器可能不怎么阻止溢出,所以能否访问p[n]的值完全是操作平台的责任,因为在我的平台上,p[30]仍然是栈空间的一部分,所以操作系统允许我修改p[30]的值,当修改p[3000]的时候,数据已经不再是我的程序划分到空间,所以系统中断了程序.
------其他解决方案--------------------
char p[];//字符数组,大小编译器确定,你说sizeof(cnode)为1那么它相当于char p[1];
至于xyz的大小肯定跟sizeof(cnode)一样。
再者,cnode(char pt[]){strcpy(p,pt);}是不安全的,strcpy是不管你p后面有多少合法的内存的。
------其他解决方案--------------------
1.char p[]肯定是char的数组类型.
2.为什么char p[]不会中断,而char* p会中断?
调试了下,发现p[]的地址和cnode对象地址都是一样的,栈上面的地址,所以赋值没有太大问题,尽管你已经溢出,处于未定义行为的状态中.操作系统允许你操作栈上的内存,毕竟这个内存块是你的程序通过提交合法分配到的.
而char* p,p因为你没初始化,p可能是很遥远的乱码地址,只要这个地址不是你的程序向操作系统成功提交的后得到的有访问权的地址,任何读写p操作系统都会中断你的程序.
------其他解决方案--------------------
自己google 柔性数组成员。
------其他解决方案--------------------