1、先看一下要找错的面试题
题目:下面这段代码有什么问题?
2、后续
大部分人看到的就是 if 判断需要放在最前面,其实还有其他的问题。
#先把题目抄一遍
#include #include #include //因为使用了memcpy函数int swap(void *a, void* b, int size){ void *p; p = malloc(size); //没判断是否分配成功 if (size <= 0)//位置太靠后 { printf("error"); return -1; } memcpy(p, a, size); memcpy(a, b, size); memcpy(b, p, size); free(p); return 0;}/* 主函数 */int main(){ char aa[] = "12344"; char bb[] = "adbde"; char* a = aa; char* b = bb; int re = 0; printf("交换前 a:%s\tb:%s\n", aa, bb); re = swap(aa, bb, 5); printf("交换后 a:%s\tb:%s\n", aa, bb); return 0;}
程序输出
交换前 a:12344 b:adbde交换后 a:adbde b:12344请按任意键继续. . .
1、说一下void* 指针
程序里面有 void
指针,void
指针是可以接收所有类型的指针的,但是其他类型的指针是不能直接接收void
指针的。
比如这样
int main(){ void *p_void = NULL; char *p_char = NULL; p_void = p_char; //void接收char类型的 return 0;}
下面这样可能是有问题的
我说是可能有问题是因为GCC、ANSI C 的编译情况是不同的。比如VC++6.0中出错,VS Stdio就正常。
int main(){ void *p_void = NULL; char *p_char = NULL; p_char = p_void; //char接收void类型 return 0;}
VC++6.0中报错信息是:error C2440: '=' : cannot convert from 'void *' to 'char *'
2、程序有什么问题?
这段代码有以下几点问题:
1、入参a
和b
都是void
类型的指针,不清楚a
和b
指向buff的长度是否都为size?
size
不要设置成int
,最好设置成unsigned int
, 而且a
和b
入参一定不能代入const xxxxx *
类型的实参;
2、 进入函数体之后应该首先判断size
是否小于等于0
、a
和b
是否为NULL
,如果size
小于等于0
,或者a
和b
存在NULL
,那其他代码将毫无意义。
3、没有if(!p)
对malloc
进行判断直接使用p
,剩余内存较低情况下malloc
一片大内存是有可能fail
的,直接使用p
就会段错,而且不建议malloc
。
4、memcpy
时因并不明确a b
指针指向buff
的长度是否都为size
,存在内存越界风险。
综上述修改代码为:
#include #include #include //因为使用了memcpy函数int swap(void *a, void *b, unsigned int len_a, unsigned int len_b){ if (!a || !b || !len_a || !len_b || len_a != len_b) { //字符串为空、字符串长度为0、字符串长度不相等,直接返回 printf("invalid param! \n"); return -1; } if (a == b) { printf("the same! \n"); return 0; } unsigned int len = len_a; char *p = (char *)malloc(len); if (!p) { printf("malloc fail! \n"); return -1; } memcpy(p, a, len ); memcpy(a, b, len ); memcpy(b, p, len ); free(p); return 0;}/* 主函数 */int main(){ char aa[] = "12344"; char bb[] = "adbde"; char* a = aa; char* b = bb; int re = 0; printf("交换前 a:%s\tb:%s\n", aa, bb); re = swap(aa, bb, 5, 5); printf("交换后 a:%s\tb:%s\n", aa, bb); return 0;}
END
转自《嵌入式Linux》的 “ 这道笔试题竟然运行不出错 ”版权归原作者所有,如有侵权,请联系删除。