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

目录

第一题:

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

改正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;
 }

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

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

欢迎各位大佬指正

评论 34
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

执久呀

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值