为什么不同定义字符数组会有两种结果?根据所学,除了结束字符外,所定义b[9]应该能放9个字符啊?
根据所学,除了结束字符外,所定义b[9]应该能放9个字符啊?在vs.net2003中实现代码如下:
char b[9];
char *s=&b[0];
strcpy(s,"12345678");//超过8个字符要溢出(不解啊)
char *ss=new char[9];
strcpy(ss,"123456789");//可以用到9个字符
推荐阅读
俺觉得不是楼上所说原因!因为strcpy都会在末尾加null。
char b[9];
空间分配在程序栈上,任何的超过其长度的操作都会引起异常
而char *ss=new char[9];空间分配在堆上
如果指针超出分配的长度,不一定会有异常的。
天哪, 都在说些什么?
两种方式没有什么本质区别,
因为字符串自动要以0结束,
因此都最多能放8个字符。
多放了都会溢出!!!
就是说, 第二种也是错误的!
只是这个错误还没有表现出来而已。
当new char[9];后面有其它的数据时,
错误才可能休现出来, 而且有各种可能的表现形式。
这种错误是最难定位和查找的, 因此要极力避免。
"我的主题也许要改成为什么ss不会堆栈异常了"
还没清楚?
你的ss分配在heap上,不是stack上。
“run-time check failure #2 - stack around the variable b was corrupted.”
正说明你在9个长度的栈空间上,要覆盖上去10个字符
……而栈被重写可能会造成严重的问题,因此运行环境报告了这个异常。
对于ss,你分配了9个长度的堆空间上,你覆盖上去10个字符,没有
报错,不等于没有错!!!
例如,假设你的代码new了一个空间a,长度为8,操作系统可能给你的地址是1000
假如你再new了一个空间b,长度为8,那么操作系统可能给你的地址是1008
现在你要对a空间strcpy一个9字节长的串,那么实际上这个串将
占据1000~1008的空间,也就是说,你的b中的数据被破坏了!
那么再这个情况下可能不会异常,只是你的运行结果不一定是你想要的东西了
假设b不是你分配的空间,而是你的运行程序的函数库或者操作系统自动new出来的
那么,如果你破坏了b,就有可能异常。
前边有dx说的非常清楚,没有报告异常不等于没有错误!
哎,哪位把strcpy的实现和程序栈和堆的概念讲给楼主吧
同意rtdb(东临碣石)
两种方式没有什么本质区别,
因为字符串自动要以0结束,
因此都最多能放8个字符。
多放了都会溢出!!!
就是说, 第二种也是错误的!
只是这个错误还没有表现出来而已。
当new char[9];后面有其它的数据时,
错误才可能休现出来, 而且有各种可能的表现形式。
这种错误是最难定位和查找的, 因此要极力避免。
而且,空间分配在程序栈上,任何的超过其长度的操作都会引起异常
而char *ss=new char[9];空间分配在堆上
如果指针超出分配的长度,不一定会有异常的。
vc6.0下测试,最后的\0被丢弃了。
如果小余9个,则最后会自动加\0。
#include "stdio.h"
#include "string.h"
void main()
{
char b[9];
char *s=b;
strcpy(s,"123456789");//超过8个字符要溢出(不解啊)
char *ss=new char[9];
strcpy(ss,"123456789");//可以用到9个字符
printf("%s\n%s\n",s,ss);
char ch1,ch2;
for(int i=0;i<9;i++)
{
ch1=s[i];
ch2=ss[i];
}
}
strcpy不检查溢出,摘自msdn
the strcpy function copies strsource, including the terminating null character, to the location specified by strdestination. no overflow checking is performed when strings are copied or appended


讨论区