资讯专栏INFORMATION COLUMN

手撕大厂出现的过的一些笔试题---------动态内存函数题

siberiawolf / 2432人阅读

摘要:目录第一题第一题分析题目程序会崩溃改正传地址调用改正返回值接收第二题原因分析第三题第一题问下面函数会输出什么第一题分析题目程序会崩溃传参数时是用的传值,我们都知道传值是不会改变函数内部的值的。

目录

第一题:

第一题分析题目程序会崩溃:

改正1:(传地址调用)

改正2:(返回值接收)

第二题:

原因分析:

第三题:


第一题:

</>复制代码

  1. //问:下面test函数会输出什么#Include#includevoid GetMemory(char*p){ p=(char*)malloc(100);}void test(void){ char*str=NULL; GetMemory(str); strcpy(str,"hello world"); printf(str);}int main(){ test();}

第一题分析题目程序会崩溃:

1. GetMemory传参数时是用的传值,我们都知道传值是不会改变函数内部的值的。

   这就导致了在外部用malloc开辟的空间返回的指向地址的指针无法改变test函数里的str指针

2.既然不会改变str指针,那str还是NULL,那么在进行strcpy函数拷贝时,会出现*NULL,

  我们都知道NULL未知的大小位置,所以对NULL解引用是非法操作,所以程序会崩溃。

3.另外一个错误也算是老生常谈的了,用了动态内存函数申请空间没有用free函数释放空间

还要记得将指针置空。

我们既然都知道了错误原因,那么改掉错误也就十分容易了。

改正1:(传地址调用)

</>复制代码

  1. //问:下面test函数会输出什么#include#include#includevoid GetMemory(char**p)//用二级指针去接收一级指针的地址{ *p=(char*)malloc(100);//*p表示的是一级指针的地址(也就是str的地址),将申请好的内存后, // 返回赋值给str,从而使外部的str的值指向了开辟好的首地址。}void test(void){ char*str=NULL; GetMemory(&str);//传地址就没问题 strcpy(str,"hello world");//此时str不再是NULL了,而是新申请的首元素地址 printf(str);//打印出hello world free(str); str=NULL;//说烂了,不说了,简称一套带走,嘻嘻!!}int main(){ test();}

改正2:(返回值接收)

</>复制代码

  1. //问:下面test函数会输出什么#include#include#includechar* GetMemory(char*p){
  2. return p = (char*)malloc(100);}void test(void){
  3. char*str = NULL;
  4. str = GetMemory(str);//返回值接收
  5. strcpy(str, "hello world");
  6. printf(str);
  7. free(str);
  8. str = NULL;}int main(){
  9. test();}

注意:上面的解法中虽然p是局部变量,在栈区上开辟,出了函数,p指针销毁,但动态内存函数申请的空间在堆区,出了函数不会被销毁,且指针p在销毁是已将开辟好的地址传给了str,所以可行。

第二题:

</>复制代码

  1. #include#includechar* GetMemory(void){ char p[]="hello world"; return 0;}void Test(void){ char* str=NULL; str=GetMemory(); printf(str);}int main(){ Test(); return 0;}

原因分析:

1.由题目可知,p数组是在代码块之内创建的局部变量,是在栈区上的,p数组出了此函数

就会被销毁,返回不出任何东西,换言之就是str 接了个寂寞(手动狗头)。

2.虽然str还是指向数组首元素地址,但是那块地址已经不存在了。所以会报错。

 如何改正呢?

最简单的方法就是将数组和指针在同一个函数中。

for example:

</>复制代码

  1. #include#includevoid Test(void){ char p[]="hello world"; char* str=NULL; str=p;//数组名就是首元素地址str指向h printf(str);}int main(){ Test(); return 0;}

这样是不是非常的easy

还有几个和上面那个类似的题

for example:

</>复制代码

  1. #includeint * test(){ int a=10; return &a;//返回a的地址 }int main(){ int *pp =test(); *pp=20;//将a赋值,成功? return 0;}

显然会报错,原因基本和上题类似

经过这两题我们应该明白了,最主要的原因就在于该值创建在栈区,且返回栈区上创建的值

在这过程其实我们也明白了,栈区的值不能被返回。改进方法之一是让这个值不是局部变量

变成全局变量,或者是静态变量(其实就是在静态区或者堆区上创建就可以了。

这里只讲个最简单的方法(因为咱这里是讲动态内存的题,不能在继续水下去了)

直接在变量前加上static

</>复制代码

  1. #includeint *test(){ static int a=10; return &a;//返回a的地址 }int main(){ int *pp= test(); *pp=20;//将a赋值,成功? return 0;}

至于static的用法有小伙伴不知第道的可以私信我,或者后期出一期讲解

第三题:

</>复制代码

  1. #include#include#includevoid Test(void){ char*str=(char*)malloc(100); strcpy(str,"hello"); free(str); if(str!=NULL) { strcpy(str,"world"); printf(str); }}int main() { Test(); return 0; }

这题主要原因:在于free函数提前释放所申请的空间,但是此时str还是指向原地址,导致strcpy进行对str的拷贝,出现了非法访问(相当于访问了一块不属于你的空间)。

解决方法:

1.可以是释放的同时将str指针置NULL,这样判断就不会成立也就不会出现后续非法访问。

 2.  也可以是在使用完后释放再置空

第一种:

</>复制代码

  1. #include#include#includevoid Test(void){ char*str=(char*)malloc(100); strcpy(str,"hello"); free(str); str=NULL; if(str!=NULL) { strcpy(str,"world"); printf(str); }}int main() { Test(); return 0; }

第二种:就是将free(str)和str放到printf之后。

</>复制代码

  1. #include#include#includevoid Test(void){ char*str=(char*)malloc(100); strcpy(str,"hello"); if(str!=NULL) { strcpy(str,"world"); printf(str); free(str); str=NULL; }}int main() { Test(); return 0; }

但仔细看题目分析一波得到前者是答案。

这篇耗时巨大,学费了的小伙伴支持一波

欢迎各位大佬指正

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/119677.html

相关文章

  • 前端开发应届生面试指南(含各大公司具体指南及面试真

    摘要:先介绍一下本人应届前端开发一枚,非科班出身,专业是化学,大学期间开始自学前端开发,在今年春招实习和秋招的时候投了一些公司,拿到一些京东拼多多虎牙等,总体来说还算满意,特地写一篇文章来总结一下面试的那些套路。 showImg(https://segmentfault.com/img/remote/1460000011897700); 先介绍一下本人应届前端开发一枚,非科班出身,专业是化学...

    sunnyxd 评论0 收藏0
  • 前端开发应届生面试指南(含各大公司具体指南及面试真

    摘要:先介绍一下本人应届前端开发一枚,非科班出身,专业是化学,大学期间开始自学前端开发,在今年春招实习和秋招的时候投了一些公司,拿到一些京东拼多多虎牙等,总体来说还算满意,特地写一篇文章来总结一下面试的那些套路。 showImg(https://segmentfault.com/img/remote/1460000011897700); 先介绍一下本人应届前端开发一枚,非科班出身,专业是化学...

    jeyhan 评论0 收藏0
  • 前端开发应届生面试指南(含各大公司具体指南及面试真

    摘要:先介绍一下本人应届前端开发一枚,非科班出身,专业是化学,大学期间开始自学前端开发,在今年春招实习和秋招的时候投了一些公司,拿到一些京东拼多多虎牙等,总体来说还算满意,特地写一篇文章来总结一下面试的那些套路。 showImg(https://segmentfault.com/img/remote/1460000011897700); 先介绍一下本人应届前端开发一枚,非科班出身,专业是化学...

    lentoo 评论0 收藏0
  • 前端记录(下)

    摘要:前言接上篇前端笔试题面试题记录上。默认值,不脱离文档流,,,,等属性不生效。。不脱离文档流,依据自身位置进行偏离,当子元素设置,将依据它进行偏离。。 前言 接上篇前端笔试题面试题记录(上)。趁清明小长假,把上篇剩下的部分也写一下,因为最近比较忙这篇已经拖了很久了。现在刚刚开始银四了,应该还是有些小伙伴在找工作,时间还不算太晚,希望本篇可以帮到这些小伙伴。 个人博客了解一下:obkoro...

    Lin_YT 评论0 收藏0
  • 前端记录(下)

    摘要:前言接上篇前端笔试题面试题记录上。默认值,不脱离文档流,,,,等属性不生效。。不脱离文档流,依据自身位置进行偏离,当子元素设置,将依据它进行偏离。。 前言 接上篇前端笔试题面试题记录(上)。趁清明小长假,把上篇剩下的部分也写一下,因为最近比较忙这篇已经拖了很久了。现在刚刚开始银四了,应该还是有些小伙伴在找工作,时间还不算太晚,希望本篇可以帮到这些小伙伴。 个人博客了解一下:obkoro...

    suemi 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<