根据所学,除了结束字符外,所定义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个字符

解决方案 »

  1.   

    俺觉得不是楼上所说原因!因为strcpy都会在末尾加null。
    char b[9];
    空间分配在程序栈上,任何的超过其长度的操作都会引起异常而char *ss=new char[9];空间分配在堆上
    如果指针超出分配的长度,不一定会有异常的。
      

  2.   

    第一种方法s被定义成指向字符数组的指针,相当于是一个字符串,而字符串在定义过程中当然需要为结束符保留一个位置,即b[8] = '\0'。
    第二种方法ss动态申请一块内存空间,并指向该内存空间,该内存空间用来存放9个字符;
      

  3.   

    char b[9];最后一位(即第十位)要保留结束符'\0'
    所以实际要占10 bytes所以应该不会溢出
    eok () 为什么说它溢出???
      

  4.   

    针对字符串而言
    最后一个字符必须是ASCII码为零的字符
    也就是'\0'char b[9];
    char *s=&b[0];
    strcpy(s,"12345678");//超过8个字符要溢出(不解啊)为什么只能存放八个字符呢?
    因为最后一个,也就是b[9]存放了'\0'char *ss=new char[9];
    strcpy(ss,"123456789");//可以用到9个字符你可以试着printf("%s", ss);
    你就知道为什么了换句话说编译器看ss, b的角度是不一样的
    一个是字符串,而另一个是字符数组
      

  5.   

    同意 zzyx(菜农) 的说法,strcpy都会在末尾加null。你用VS.net2003我还没用过,菜农的说法我在一本书里看过,这里可能与new关词有很大关系。即.net对new的处理,很有些不同。
      

  6.   

    天哪, 都在说些什么?两种方式没有什么本质区别,
    因为字符串自动要以0结束,
    因此都最多能放8个字符。
    多放了都会溢出!!!就是说, 第二种也是错误的!
    只是这个错误还没有表现出来而已。
    当new char[9];后面有其它的数据时,
    错误才可能休现出来, 而且有各种可能的表现形式。
    这种错误是最难定位和查找的, 因此要极力避免。
      

  7.   

    天哪, 都在说些什么?两种方式没有什么本质区别,
    因为字符串自动要以0结束,
    因此都最多能放8个字符。
    多放了都会溢出!!!就是说, 第二种也是错误的!
    只是这个错误还没有表现出来而已。
    当new char[9];后面有其它的数据时,
    错误才可能休现出来, 而且有各种可能的表现形式。
    这种错误是最难定位和查找的, 因此要极力避免。
      

  8.   

    你试试用
    printf("%s",ss);
    你就会明白什么叫出错了b[9]应该能放9个字符啊,没有错,如果放字符串的话只能是8个字符组成的字符串
    最后一个'\0'也是一个字符,是特别字符 字符串结束符
      

  9.   

    我在vc6.0在试了
    char b[9];
    char *s=&b[0];
    strcpy(s,"123456789");//超过8个字符要溢出(不解啊)
    char *ss=new char[9];
    strcpy(ss,"123456789");//可以用到9个字符char ch1 = s[9];
    char ch2 = ss[9];经过调试ch1,ch2都为'\0'(ascll码)
    楼主也试试吧
      

  10.   

    char *s=&b[0];兄弟,不是我说你,有你这样写的吗?写成:char *s=b;要是有溢出你找我麻烦。
      

  11.   

    注意不报错
    不代表没有错
    s[9],ss[9]不属于s
    有可能s[9],ss[9]被修改
    (可能被分配给别的变量)
    如果'\0'被修改成其它的
    就有问题了.
    假如:
    内存ss如下:
    12345689'\0'XXXXXXXXXxxx'0'
    如果'\0'被改成字符1.
    那么ss就变成了:
    123456891XXXXXXXXXxxx
      

  12.   

    觉得 zzyx(菜农) 说的有道理
    应该是堆栈的问题
    char b[9]毫无疑问,可以放9个字节的东西
    但是怎么放,怎么取是问题
    c语言处理字符有其特殊约定
    在栈中有边界问题
    但是在堆中,越界会发生意想不到的错误
    事实上,在数组中,连续定义的字符缓冲区也可能overlap,但不会提示任何错误
      

  13.   

    对不起(风前横笛斜吹雨),char *s=b;还是出错。
    vc2003在测试:
    char b[9];
    char *s=&b[0];
    strcpy(s,"123456789");//超过8个字符要溢出(不解啊)
    char *ss=new char[9];
    strcpy(ss,"123456789");//可以用到9个字符char ch1 = s[9];
    char ch2 = ss[9];经过断点调试ch1和ch2都为0(ascll码),也就是说不存在溢出
    但是接着运行下去
    Run-Time Check Failure #2 - Stack around the variable 'b' was corrupted.
    翻译过来就是“运行时检查错误#2-变量b堆栈异常”
    所以说,我的主题也许要改成为什么ss不会堆栈异常了。
      

  14.   

    "我的主题也许要改成为什么ss不会堆栈异常了"还没清楚?
    你的ss分配在heap上,不是stack上。“Run-Time Check Failure #2 - Stack around the variable 'b' was corrupted.”正说明你在9个长度的栈空间上,要覆盖上去10个字符(包括了一个null)
    ……而栈被重写可能会造成严重的问题,因此运行环境报告了这个异常。对于ss,你分配了9个长度的堆空间上,你覆盖上去10个字符(包括了一个null),没有
    报错,不等于没有错!!!
    例如,假设你的代码new了一个空间A,长度为8,操作系统可能给你的地址是1000
    假如你再new了一个空间B,长度为8,那么操作系统可能给你的地址是1008现在你要对A空间strcpy一个9字节长(包括了null)的串,那么实际上这个串将
    占据1000~1008的空间,也就是说,你的B中的数据被破坏了!
    那么再这个情况下可能不会异常,只是你的运行结果不一定是你想要的东西了假设B不是你分配的空间,而是你的运行程序的函数库或者操作系统自动new出来的
    那么,如果你破坏了B,就有可能异常。前边有dx说的非常清楚,没有报告异常不等于没有错误!
    哎,哪位把strcpy的实现和程序栈和堆的概念讲给楼主吧
      

  15.   

    #include <iostream>
    using namespace std;
    int main()
    {char b[9];
    char *s=b;
    strcpy(s,"123456789");
    char *ss=new char[9];
    strcpy(ss,"123456789");char ch1 = s[9];
    char ch2 = ss[9];
    printf("%s",s);
    cin.ignore();
    }
    输出“123456789”
    得到结果是在win32控制台下的编程下不会有出错,但在MFC和API编程环境下就有
    Run-Time Check Failure #2 - Stack around the variable 'b' was corrupted.
    报错,对于strcpy的实现和程序栈和堆的概念我真的一无所知,所以还烦请zzyx(菜农)
    说说!win32控制台下没有报异常,是否仍然不该这样分配?
      

  16.   

    VC6.0下测试过了,没有问题!#include "stdio.h"
    #include "string.h"void main()
    {
    char b[9];
    char *s=b;
    strcpy(s,"123456789");
    char *ss=new char[9];
    strcpy(ss,"123456789");//可以用到9个字符
    printf("%s\n%s\n",s,ss);
    }
      

  17.   

    同意rtdb(东临碣石)
    两种方式没有什么本质区别,
    因为字符串自动要以0结束,
    因此都最多能放8个字符。
    多放了都会溢出!!!就是说, 第二种也是错误的!
    只是这个错误还没有表现出来而已。
    当new char[9];后面有其它的数据时,
    错误才可能休现出来, 而且有各种可能的表现形式。
    这种错误是最难定位和查找的, 因此要极力避免。而且,空间分配在程序栈上,任何的超过其长度的操作都会引起异常
    而char *ss=new char[9];空间分配在堆上
    如果指针超出分配的长度,不一定会有异常的。
      

  18.   

    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
      

  19.   

    讨论了半天,我都有点晕忽了,最后我找书复习了一下,发现自已很菜,数组都没学好,这里我想必要澄清一下
    char a[5];//定义了5个整数,分别是a[0] a[1] a[2] a[3] a[4]
    那么a[5]呢,根本不存在,a[4]要放结束符,所以只能放4个字符,不明这个才是我真正的错误,后面请大家看明白了再跟贴:
    VC.net2003
    在Win32控制台编程(类似于DOS界面的编程)测试
    #include <iostream>
    using namespace std;
    int main()
    {char b[9];
    char *s=b;
    strcpy(s,"12345678超过");//超过8个字符要溢出(不解啊)
    char *ss=new char[9];
    strcpy(ss,"了原定义大小12345678");//可以用到9个字符
    printf("%s",b);
    printf("%s",s);
    printf("%s",ss);
    cin.ignore();
    delete[]ss;
    }
    所得到结果输出"12345678超过12345678超过了原定义大小12345678"
    也就是说在win32控制台下的处理异常宽容。在MFC和API编程环境下则会报错
    Run-Time Check Failure #2 - Stack around the variable 'b' was corrupted.所以说,我的主题不是改成为什么ss不会堆异常了,而是数组要这么个理解了。我的另一个问题还没有人解答,请有能力的朋友不妨看看http://expert.csdn.net/Expert/topic/2162/2162022.xml?temp=.9801142