读字符串越界

写C程序的时候经常会用到读字符串。当为字符串数组开辟的空间不够大的时候,输入字符数大于数组大小会发生不可预知的运行时的错误,这种错包括1> 运行时错误,2>结果错误,3,>段错误。遗憾的是C语言本身没有提供检测这种的错误的机制。下面根据代码分析产生错误的类型以及原因。


分析1

#include 

int main(void)
{
	int sum = 0, i = 0;
	char input[5];

	while (1) {
		sum = 0;
		scanf("%s", input);
		for (i = 0; input[i] != '\0'; i++)
			sum = sum*10 + input[i] - '0';
		printf("input=%d\n", sum);
	}
	return 0;
}
若输入1234567,输出为1234567;

上面代码,若输入12345678会输出123456740。

为什么会出现123456740,而不是输出12345678呢?如果了解函数栈结构我们会指导 i 的地址就是input[8]的地址。当循环进行八次之后i=8,input[8]=0x08;经过这样的运算12345678*10+8-48,得到1234456740。当然得到这个值也取决于机器的字节存放顺序,是大端法还是小短发,得出这样的结果也证明本机是采用的是大端法。若是小端法会得到另外一种结果。


分析2

#include 

int main(void)
{
	int sum = 0, i = 0;
	char input[5];
	while(1)
	scanf("%s", input);
	for (i = 0; input[i] != '\0'; i++) {
		if (input[i] < '0' || input[i] > '9') {
			printf("Invalid input!\n");
			sum = -1;
			break;
		}
		sum = sum*10 + input[i] - '0';
	}
	printf("input=%d\n", sum);   
	}
	return 0;
}
运行./main

         输入12345678

输出Invalid input!

解释见分析一。不会产生段错误。


分析3

若把分析2代码中while循环去掉,再输入12345678901234567,17个数字会超过main函数中sum的地址的范围,会发生段错误。

但是在代码2中输入这17个数字则不会产生段错误?这是为什么呢?这是因为如果某个函数的局部变量发生访问越界,有可能并不立即发生段错误,而是在函数返回的时候发生段错误。


代码来源  http://learn.akae.cn/media/ch10s04.html

你可能感兴趣的:(C/C++,c语言,访问越界)