文章转载自:http://www.pythonheidong.com/blog/article/2549/
这篇文章涉及到的都是一些C语言的基础知识,是从一篇英文文章中部分翻译和加入我自己的认识!!!!
1. gets()函数
Q:下面的代码中隐含着安全问题,能发现吗?
1 #include<stdio.h> 2 int main(void) 3 { 4 char buff[10]; 5 memset(buff,0,sizeof(buff)); 6 7 gets(buff); 8 9 printf("\n The buffer entered is [%s]\n",buff); 10 11 return 0; 12 }
A:问题在于gets()函数,这个函数是接收标准输入的一串字符串,并且没有检查字符串缓冲区的大小就
直接拷贝到buff数组中,这可能导致在写入buff内存时溢出,可以使用fgets()函数代替这个函数,
char *fgets( char *str,int n,FILE *stream );
2.strcpy()函数
Q:下面代码是一个密码验证的过程,是否可以在不知道密码的情况下验证通过
1 #include<stdio.h> 2 #include <string.h> 3 4 int main(int argc, char *argv[]) 5 { 6 7 char passwd[10]; 8 int flag = 0; 9 memset(passwd,0,sizeof(passwd)); 10 11 strcpy(passwd, argv[1]); 12 13 if(0 == strcmp("LinuxGeek", passwd)) 14 { 15 flag = 1; 16 } 17 18 if(flag) 19 { 20 printf("\n Password cracked \n"); 21 } 22 else 23 { 24 printf("\n Incorrect passwd \n"); 25 26 } 27 return 0; 28 }
A:strcpy()函数没有验证输入的字符串长度,所有在执行时可能出现写内存出现溢出,这很危险,如这代码,
flag是初始化为0的,当内存溢出时可能会写到flag内存中,这会使得flag内存不为0,即使不执行if语句的
比较flag也为真,所以就相当于密码正确
如: $ ./psswd aaaaaaaaaaaaa 输出: Password cracked
可以使用strncpy()函数代替
现在编译器也发现这种情况,所以在为程序分配内存时是分散的分配内存,如果要看到上面执行的情况,使用gcc的话
可以使用 ‘-fno-stack-protector’参数(我没验证)
3.main()函数的返回类型
Q:下面代码是否能编译通过?是否还存在其他问题
1 #include<stdio.h> 2 3 void main(void) 4 { 5 char *ptr = (char*)malloc(10); 6 7 if(NULL == ptr) 8 { 9 printf("\n Malloc failed \n"); 10 return; 11 } 12 else 13 { 14 // Do some processing 15 16 free(ptr); 17 } 18 19 return; 20 }
A:对于现在的编译器这段代码是可以编译通过的,不过是会有警告,main()返回类型最好使用int类型,
当一个函数执行结束时最后返回一个状态值,现在C/C++返回一个0值表示程序正常退出,否则有异常.
4.内存泄露
Q:下面代码执行结果会出现内存泄露吗?
1 #include<stdio.h> 2 3 void main(void) 4 { 5 char *ptr = (char*)malloc(10); 6 7 if(NULL == ptr) 8 { 9 printf("\n Malloc failed \n"); 10 return; 11 } 12 else 13 { 14 // Do some processing 15 } 16 17 return; 18 }
A:其实内存泄露是个很严重的问题,其实上面代码执行结果不会出现内存泄露,虽然没有使用free()
回收内存,但是当程序执行结束后程序里分配的内存会自动释放,如果是分配的内存放到一个死循环里
就会出现严重的内存泄露,或者程序一直执行着,动态分配的内存会一直占有着无法释放.
有篇文章介绍了内存泄露的检测方法:http://www.cnblogs.com/skynet/archive/2011/02/20/1959162.html
5.free()函数
Q:下面代码执行时输入如 ‘freeze’会崩溃但输入如t ‘zebra’就不会为什么?
1 #include<stdio.h> 2 3 int main(int argc, char *argv[]) 4 { 5 char *ptr = (char*)malloc(10); 6 7 if(NULL == ptr) 8 { 9 printf("\n Malloc failed \n"); 10 return -1; 11 } 12 else if(argc == 1) 13 { 14 printf("\n Usage \n"); 15 } 16 else 17 { 18 memset(ptr, 0, 10); 19 20 strncpy(ptr, argv[1], 9); 21 22 while(*ptr != 'z') 23 { 24 if(*ptr == '') 25 break; 26 else 27 ptr++; 28 } 29 30 if(*ptr == 'z') 31 { 32 printf("\n String contains 'z'\n"); 33 // Do some more processing 34 } 35 36 free(ptr); 37 } 38 39 return 0; 40 }
A:这个问题主要是指针移到的问题,当输入如‘zebra’这样的字符串('z'开头)时,ptr指针没有移到,所以
ptr指针指向的内存还是malloc分配的原内存的起始地址,但是输入‘freeze’时,ptr指针移到了,已经不是指向原来
分配的内存的起始地址了,所有free时就会出错
题外话:在实现如strcpy的函数时,如下
1 char *strcpy(char *strDest, const char *strSrc) 2 { 3 assert((strDest != NULL) && (strSrc != NULL)); 4 5 if(strDest == strSrc) 6 return strDest; //注意这个.. 7 8 char *pstr = strDest; //保存原始地址 9 whil