字符串初始化与数组越界问题。

string p1="abcd";

char *p2="abcd";

char p3[]="abcd";  //sizeof(p3)=5;

字符串结尾都有系统自动补‘\0’,可用作判断字符串结束标志

字符数组和字符串最明显的区别就是字符串会被默认的加上结束符'\0'

char p4[4]="abcd";//在定义时系统提示字符太长编译不通过。"abcd"长度为5


字符数组并不要求最后一个字符为'\0'.是否加入'\0',完全由系统需要决定。但是我们写代码时要求字符数组初试化要求最后一个字符必须是'\0',类似char p[4]={'a','b','c','d'};这样的定义是错误的,虽然可以通过编译。

字符串初始化与数组越界问题。_第1张图片



但是如果定义时为  char p[5];在将5个字符复制到字符数组中,编译时不会出错,但是运行时输出结果可能会多出几位。(遇到结束位'\0'才会停止) ,见test2()函数



void test1()

{  

   char str[10];  
  char*str1="0123456789"; 
  strcpy(str,str1);
  cout< }

字符串长度为10,还有一个结束符'\0',所以共11个字符,str1数组大小为10,这里越界了。

虽然越界了,但是并不报错,编译运行都可正常通过。(字符数组不要求最后一个字符为'\0',是否需要加入'\0',完全由系统决定


但是代码改为

字符串初始化与数组越界问题。_第2张图片


若数组长度不足以容纳整个字符串,则程序运行崩溃。




windows栈空间从高地址(栈底)到低地址(栈顶)方向。所以根据变量定义的顺序及连续性,可知两个字符串在排列为1234'\0'123456789'\0'.所以发生上述图片中所说现象。(覆盖本程序内其他空间数据,程序可以运行


将字符串定义前后顺序颠倒则为123456789'\0'1234'\0'此时目标地址溢出,程序输出结果后崩溃。(有可能覆盖到本程序之外其他程序的有用数据,程序报错




test2()

{

 char str1[10],str2[10];
  for(int i=0;i<10;i++)
  {
  str1[i]='a';
  }
  strcpy(str2,st
r 1);
  cout<

 }

字符串初始化与数组越界问题。_第3张图片

----------aaaaaaaaaa内存分布。执行strcpy(str2,str1)在str1后面直到遇到结束符'\0'才停止复制。超出程序定义空间。

字符串初始化与数组越界问题。_第4张图片

这里最大问题是str1没有结束符。因为strcpy的第二个参数应该是一个字符串常量(字符串默认带有结束标志),而该函数就是利用第二个参数的结束符来判断复制是否结束。所以在for循环后面加上str1[9]='\0';

在DEV中上例可以执行成功。但是下例可是直接崩溃,请问为什么?


test3()

{

char str1[10],str2[10];
  for(int i=0;i<10;i++)
  {
  str2[i]='a';
  }
  strcpy(str1,str2);
  cout<return 0;

}

字符串初始化与数组越界问题。_第5张图片

aaaaaaaaaa----------  和上面相同基本都会崩溃,只是各个编译器处理方式不同而已。

字符串初始化与数组越界问题。_第6张图片


答案参见  面试例二图片下的解释。


总结:对字符数组操作结尾一定要自己添加结束标志'\0'.

你可能感兴趣的:(C/C++)