来源:公众号【编程珠玑】
作者:守望先生
ID:shouwangxiansheng
近期文章
貌似很久没有更新文章了,前两天更新了一篇《想后台运行没想到导致磁盘满了》,里面涉及的内容比较广,可惜看的人不多。今天来看到小题,复习一下。
下面的输出结果是什么?为什么
//来源:公众号编程珠玑//作者:守望先生#include#include#includevoid getmemory(char *p) {
p=(char *) malloc(128);strcpy(p,"hello 编程珠玑");
}int main( ) {char *str = NULL;
getmemory(str);printf("%s\n",str);free(str);return 0;
}
结果
先不要看下面的分析,上面的代码中,你发现了哪些问题呢?
这是一道非常常见的面试题,很多人一眼看过去就知道问题在哪了,是的,程序运行异常,可能出现Segmentation fault。
分析
首先第一个问题在于,str的值是没有变的,也就是说执行getmemory之后,str还是NULL,即不能达到预期,使得str指向一个保存着字符串的内存区域。而这里主要考察的是对C语言中参数值传递的理解。更加详细的解释可以参考《函数参数的传值和传指针有什么区别?》。
而真正导致Segmentation fault的原因是printf中,str是NULL,而访问NULL位置的内存是非法的。这一点在《解引用NULL为什么会导致程序挂死?》中也有解释。
另外使用strcpy进行字符串的拷贝也是不推荐的,可能有缓冲区溢出的风险,推荐使用strncpy。关于缓冲区溢出,可以参考《C语言入坑指南-缓冲区溢出》。
修正
//来源:公众号编程珠玑//作者:守望先生#include#include#includevoid getmemory(char **p) {
*p = (char *) malloc(128);if(NULL == *p){printf("get memory failed\n");return;
}strncpy(*p,"hello 编程珠玑",sizeof("hello 编程珠玑"));
}int main( ) {char *str = NULL;
getmemory(&str);if(NULL != str){printf("%s\n",str);
}free(str);
str = NULL;return 0;
}
![7ff2aeadc430052e556ee565f0920a42.png](https://i-blog.csdnimg.cn/blog_migrate/1e077ef9d0f51a43423254f897406b76.jpeg)
相关精彩推荐
![f3bf2a17bb12a9fe46d25f5652fbd93b.png](https://i-blog.csdnimg.cn/blog_migrate/bc60bec95c3aab72458ff4d5890f2c65.jpeg)
![15a921b213ce105ef72115caac873f66.png](https://i-blog.csdnimg.cn/blog_migrate/e817969f4d9626d52468742311b1f110.jpeg)