几个常见的程序错误

前一段时间遇到一个很容易的犯的错误,这段程序很值得借鉴,下面是源程序,因为是错误的,所以我给注释了。

// #include <string.h>
// #include <stdlib.h>
// strReverse()
// {
// 	char *src = "cdata";
// 	char *dest = NULL;
// 	int len = strlen(src);
// 	dest = (char*)malloc(len);
// 	char *d = dest;
// 	char *s = src[len];
// 	while(len--!=0)
// 		*d++=*s--;;
// 	printf("%s\n",dest );
// 	return 0;
// }

真的是很考验基本功的程序,下面是正确的程序。

#include <string.h>
#include <stdlib.h>
#include <stdio.h>   //缺少一个头文件
int main()
{
	char *src = "cdata";
	char *dest = NULL;
	int len = strlen(src);   //len是5 ,但是字符串是从0开始的。所以下面len-1,以及分配多一个内存。
	dest = (char*)malloc(len+1);  
	char *d = dest;
	char *s = &src[len-1];  //-1个,因为数组是从0开始的。
	while(len--!=0)
		*(d++)=*(s--);   //应该是里面的内容,试想一下就可以了。
	*d = '\0';			//加上结束符。
	printf("%s\n",dest );
	getchar();
	return 0;
}



还有关于指针的,确实头晕,但是记住就好。

代码段1:
void GetMemeory(char *p){
p=(char*)malloc(100);
}
void Test() 
{ 
char *str=NULL; 
GetMemory(str); 
strcpy(str,”helloworld”); 
printf(str); 
} 
运行Test函数会有什么结果?
代码段2:
char *GetMemory(void){
char p[]="helloworld";
return p;
}
void Test(void)
{
char *str=NULL;
str=GetMemory();
printf(str);
}
运行Test函数会有什么结果?
代码段3:
void GetMemory(char **p,int num)
{
*p=(char*)malloc(num);
}
void Test(void)
{
char *str=NULL;
GetMemory(&str,100);
strcpy(str,"hello");
printf(str);
}
运行Test函数会有什么结果?
代码段1:出错。
原因:Test在调用GetMemory时,会把指针str复制一份,作为p传递给GetMemory。也就是说Test里的str和GetMemory里的p是两个不同的指针,对p做的任何操作都不影响str,str一直是空指针。然后再向空指针调用strcpy就会出错。

代码段2:输出一段乱码。
原因:这个结果和堆栈有关。Test调用GetMemory函数时,会在内存堆栈区中给GetMemory函数开辟一块新的空间(下称“区域A”),然后GetMemory的参数、局部变量等都在区域A里,于是GetMemory里面的局部变量char p[]也指向区域A里的字符串"helloworld"(注1)。问题在于GetMemory函数结束后,区域A会被释放,里面的一切内容失去意义,变成不可预测的随机值。GetMemory把p作为返回值返回给Test中的指针str,GetMemory结束后,str仍然指向区域A中的某位置,但这个位置的值已经变成随机值,所以printf会打印出随机字符,即乱码。

注1:这里我不是很确定。根据我以前的知识,常量字符串"helloworld"应该不在堆栈区里,不会随着函数的执行与结束而变化,代码段2理应输出"helloworld",但执行结果还确实是乱码,我目前只能想到上述解释。

代码段3:输出hello。
原因:由于Test和GetMemory之间传递的是指针的指针,所以和代码段1不同,这次两者修改的是同一个指针。GetMemory结束后,Test中的str指向堆里一个100字节的区域,然后再用strcpy向其中复制一个字符串'hello",所以输出结果也就是"hello"。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值