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

举报
执久呀 发表于 2022/02/18 12:19:13 2022/02/18
【摘要】 ​ 目录第一题:第一题分析题目程序会崩溃:改正1:(传地址调用)改正2:(返回值接收)第二题:原因分析:第三题:第一题://问:下面test函数会输出什么#Include<stdio.h>#include<stdlib.h>void GetMemory(char*p){ p=(char*)malloc(100);}void test(void){ char*str=NULL; Get...

 目录

第一题:

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

改正1:(传地址调用)

改正2:(返回值接收)

第二题:

原因分析:

第三题:



第一题:

//问:下面test函数会输出什么
#Include<stdio.h>
#include<stdlib.h>

void 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:(传地址调用)

//问:下面test函数会输出什么
#include<stdio.h>

#include<stdlib.h>

#include<string.h>

void 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:(返回值接收)

//问:下面test函数会输出什么
#include<stdio.h>

#include<stdlib.h>

#include<string.h>

char* GetMemory(char*p)
{

	return p = (char*)malloc(100);

}

void test(void)

{
	char*str = NULL;

	str = GetMemory(str);//返回值接收

	strcpy(str, "hello world");

	printf(str); 

	free(str);

	str = NULL;

}
int main()
{
	test();

}

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


第二题:

#include<stdio.h>

#include<stdlib.h>

char* 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:

#include<stdio.h>

#include<stdlib.h>

void Test(void)
{
 char p[]="hello world";

  char* str=NULL;

  str=p;//数组名就是首元素地址str指向h

  printf(str);

}

int main()

{
  Test();

 return 0;

}

这样是不是非常的easy

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

for example:

#include<stdlio.h>

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

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

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

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

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

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

直接在变量前加上static

#include<stdlio.h>

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

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

第三题:

#include<stdio.h>

#include<stdlib.h>

#include<string.h>

void 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.  也可以是在使用完后释放再置空

第一种:

#include<stdio.h>

#include<stdlib.h>

#include<string.h>

void 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之后。

#include<stdio.h>

#include<stdlib.h>

#include<string.h>

void 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;
 }

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

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

欢迎各位大佬指正

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。