原帖由 iptton 于 2006-12-26 11:49 发表
只申请两个空间输入超过两个字符会造成溢出。。。
每输入一个字符串,都会自动在后面加上'\0'为结束符
也就是说你输入了两个字符,要有容纳三个字符的空间来放
如前面一些帖子讨论的
当你使用了没有向系统 ...
当然是2个。不过实际上比较复杂。
原则上来说,对象的定义语句会对该对象分配这个对象所需的存储。然而对数组来说,主要有两个问题:
第一,C语言中对数组的支持相当不完整,它只不过是对一组连续存储的对象进行访问的语法简化。就是说,如下语法形式是等价的。
arr[j] == j[arr] == *(arr+j);
数组名就是数组首地址,而不会进行任何下标访问限制,并且作为函数参数传递的必然是这个地址。
scanf函数获得了这个地址,并试图向这个地址上写入数据,它并不知道这个地址上的数组到底有多大,你输入多少都会被写进去,用%s所写的字符串还要加上一个'\0'字符。
所以你写3个字符实际上是4个字符,而7个字符实际上是8个字符。
第二,自动变量是在运行栈上分配空间的,如果你向超过数组下标范围的地方写入数据,几乎可以肯定会造成在该运行栈上分配的其他自动变量的改动甚至是破坏整个运行栈结构。数据输入多了自然会造成程序崩溃。这是非常常见的C语言“缓冲区溢出”安全问题的主要原理。
第三,内存中分配变量有时不是紧挨着放置的,这其中有关于“对齐”的要求。
所谓对齐问题,简单的说就是按2的指数倍的内存位置进行放置。由于CPU在读写内存时要通过数据总线,而数据总线是4字节或8字节等,而每个读写指令肯定最自然的方式就是一次读写4个字节或8个字节。为了提高CPU访问内存的效率,防止对一个变量需要进行两次读取或写入才能完成访问,通常在分配其内存位置时都把它放在按2、4或8个字节对齐的位置。这种情况下,
char a[2];
会在运行栈上分配2个字节,而按32位机器的对其要求还有2个字节的填充空余,总共是4个字节,而
char a[5];
的填充就会是3个字节。由此可以推断你可以输入3个获7个数字是因为额外的字符和'\0'被放在这些填充位置上。再多就会破坏栈结构了。
原帖由 powerwind 于 2006-12-26 16:09 发表
请问楼上两位,我想知道,究竟C语言里的数组的内存空间是不是连续啊??
原帖由 黯然销魂 于 2006-12-26 16:23 发表
自己写个程序, 逐个print每个元素的地址, 看看是不是连续的就知道了.
原帖由 iptton 于 2006-12-26 16:43 发表
我记错了。。。
我看到的资料是下面这种情况:
char a;
char b;
a 与 b两块内存是否相邻没被定义....
而非数组元素。。。
欢迎光临 工大后院 (https://www.gdutbbs.com/) | Powered by Discuz! X3.5 |