一个简单sizeof的问题,希望不会难倒你!

huche 2004-08-07 10:41:35
我想大家都知道这两题的结果:
1.
char str1[] = "hello";
cout << sizeof(str1) << endl;
输出结果是:6

2.
char str2[5];
strcpy(str2, "hello");
cout << sizeof(str2) << endl;
输出结果是:5

但是,我查看了内存,实际上str1和str2都占了6个字节的内存,最后一个字节是0x00,为什么1和2的结果会不一样呢?

...全文
507 点赞 收藏 30
写回复
30 条回复
切换为时间正序
请发表友善的回复…
发表回复
kenyle 2004-08-09
楼上用sizeof对数组的理解看来还没有理解清透,你可以看一下有关清华大学钱能写的C++上面很清楚的写出来了数组中在内存中的分配问题,好象是在指针那一章写的比较清楚。
回复
shenyiwen 2004-08-09
楼上理解有误。C字符串就是数组,和链表无关。以\0作结尾只是一种人为的约定。
不要把简单的问题想复杂了。
回复
庄鱼 2004-08-09
这是一个很典型的字符串的表述问题,争论的焦点在于字符串是什么,是指针还是数组,抑或是其它。
从字符串的本身来看,很象是数组,但比数组要多一个字节。从书写习惯来看,字符串更像是指针,有指针的许多特性。但是,字符串就是字符串,既不是数组也不是指针,其实际上是一种链表,其特性与链表没有丝毫的分别,由于缺乏向下的指针,因而被隐饰了起来,这位许多初学C语言的人带来了不小的麻烦:由于其既象是数组又像是指针,很容易与这两种概念相混淆,为以后的深入学习带来障碍。加上国内一些出书教学的人,自己在这方面不甚了解,以至于数组指针相互混用尤为严重,由于概念的不清晰,在遇到结构、类、对象等一些复杂类型时,往往会觉得指针不好理解。
数组的大小是固定的,无论是定数组还是不定数组,在声明的时候其大小就已经明确了下来。对sizeof这种占位运算符,其大小在整个函数的生存周期内是固定不变的。其访问与调度可以通过下标变量来明确。通常,数组的问题用来解决的是存储的空间问题,而指针则是面对的数据的调用。对字符串来说,用数组表现得好处是可以进行特殊的处理,但不符合C的早期约定。用指针表述的时候,又容易掩盖字符串本身的性质,而造成数据的泄漏。
如果,将字符串作为一个隐式的指针链表,那末又会怎样呢?我们发现这将会很好地解释字符串的各种行为:必须要有起始段口,要有结束标志,可以正向索引,不能反向索引(虽然你可以那样去做,但不能保证结果都是正确的),再C的规范中,是将字符串作为一种结构加以规范的,因而有了string的概念,并衍生出一系列的相关函数。但是在字符串的常规表示中,很少有人真正严格的用string结构类型的方式去表达,原因通常是嫌其麻烦。直到C++的出现,才因大规模的程序开发而使得这问题得到足够的重视,当更规范灵活的方法出现以后,才使得变成着抛却现有的习惯而转用更方便更安全的方式。BCB的AnisString就是一个很典型的例子。
但对DOS用户来说,使用char[]或char*依然很流行,尤其是在小程序上更是如此,当然,只要我们足够的小心,选用何种方式完全是处置个人的喜好,其结果也都是一样的。除非我们并不知道自己都干了些什么或将要去做啥;毕竟做上帝的感觉就该是这样无所不能。
我想,在这里的致力于编程的程序员们,维持你们热爱这一事业的真正动因,并不是其微薄的薪水、超长的工作时间、无限的竞争压力、恶劣的生存环境,而是因为我爱我能控制自己:像上帝一样的创造自己的婴儿;我们尊重的不是金钱也不是权威,而是心灵里的那份真诚,这样我们的代码才会强壮无比,即便是像一个小小的字符串处理,我们也会认真对待。
回复
lloyd_wu 2004-08-09
问题不在于你是否拷贝了什么给str2,而在于你定义了str2的长度是5,strcpy函数的定义和用法你看看就明白了!也没有什么复杂的!
回复
Jedimaster 2004-08-09
最后的是\0屏幕不会显示出来的
回复
lionlsl 2004-08-08
这种问题是这样的:
你用数组str2[]是定义了5个,sizeof(str2)当然是5,而直接赋值当然不用我说了
回复
jjyyis 2004-08-08
char str2[5];
strcpy(str2, "hello"); // 缓冲区溢出
cout << sizeof(str2) << endl;

这样的代码很容易被人利用!
回复
iwdc 2004-08-08
大家讲的很清楚,我终于明白了
回复
newshowgua 2004-08-08
char str1[] = "hello";
隐式的创建数组,数组元数编译器根据等号后的表达式确定。
"hello" 中双引号告诉编译器它是字符串 所以等价为 {'h','e','l','l','o','\0'}
6个字节。
char str2[5]
显式的创建了一个5个字节的数组。
回复
hszr99 2004-08-08
sizeof是测试你占用的字节数,"holle"再加上'\0',正好是六字节。
str2定义是就是五个字节,当然是五了。
回复
rr12 2004-08-08
编译器可能不是像你一样在内存里查看内容而得到串长度,他是这样做的:

以你的第一个例子那样生成的变量等效于

char str1[6];//因为"hello\0"共有6个字符

//你要用"abc"那就是:
char str1[4];
//你要用"appleTree"那就是:
char str1[10];

你的第二个例子不管溢不溢出,编译器看到的是:

char str2[5];

所以他只关心

char str[x];

中那个x,sizeof(str)值就为x.
回复
开心小肉妞 2004-08-08
sizeof 数组名 得到是数组的元素个数,第一个当然带上/0是6个数了,第二个你定义的数组就5个元素。。。
回复
rendering 2004-08-08
溢出了
只是碰巧没出问题而已
回复
chatterley 2004-08-07
附上:在2中的strcpy(str2,"hello") ‘\0’被截了。
回复
chatterley 2004-08-07
1.
char str1[] = "hello";//因为字符串是hello\0,所以总共6个。这里的str1[]就是strl[6]所以sizeof(str1)为6
cout << sizeof(str1) << endl;
输出结果是:6

2.
char str2[5];//这里数组是5个字节,当然sizeof(str2)为5拉
strcpy(str2, "hello");
cout << sizeof(str2) << endl;
输出结果是:5
回复
sharkhuang 2004-08-07
第一个是编译器自动帮你吧[6]的6添上了.
回复
freefalcon 2004-08-07
你举的例子不是同一类型,没有可比性,指针是整型的,当然是4个字节。

——char str2[5];的类型为长度为5的字符数组,sizeof当然是5
回复
freefalcon 2004-08-07
我要晕了

下面的代码
char one_byte;
strcpy((char*)&one_byte, "hello");
你看看内存,它实际也用了6个字节!
回复
gernal_dn 2004-08-07
sizeof 在获得动态分配的对象大小时,会到heap里对象的附加头部查一下,如果是静态分配的,做这事的根本就是编译器!
回复
huche 2004-08-07
To freefalcon(心宇—小小菜鸟想高飞)
你举的例子不是同一类型,没有可比性,指针是整型的,当然是4个字节。
回复
发动态
发帖子
新手乐园
创建于2007-09-28

3.2w+

社区成员

C/C++ 新手乐园
申请成为版主
社区公告
暂无公告