关于动态内存管理中的常见练习题

简介: 关于动态内存管理中的常见练习题

前言

学习完C语言中的动态内存管理,大家开始利用动态内存管理来去开辟空间,经过一顿狂敲代码后,发现了问题,程序要么崩掉,要么运行不起来。小编现在给大家分享动态内存中常见的练习,如有谬误,欢迎指正

练习1:

void GetMemory(char* p)
{
  p = (char*)malloc(100);
}
void Test(void)
{
  char* str = NULL;
  GetMemory(str);
  strcpy(str, "hello world");
  printf(str);
}

运⾏Test 函数会有什么样的结果?

敲完代码,运行一下,程序崩掉啦。这里的GetMemory()函数,采用的是值传递,形参是实参的一份临时拷贝。p和str是各自独立的两个指针,GetMemory()函数让p开辟了一个内存空间。但是(重点),p的值最初是在str中拷贝的,拷贝完之后,两个指针没有任何关系。当GetMemory()函数结束后,p的内存就被释放掉了,然后执行srecpy(),此时str仍然是一个空指针,这个程序也就无法被访问。

还有一个问题是,GetMemory()中申请的内存空间没有被释放掉,存在内存泄漏问题。

改进后的代码

void GetMemory(char** p)//形参用二级指针接收,此时p里面存的是str的地址
{
  *p = (char*)malloc(100);//*p得到str,让str指向新开辟的空间
}
void Test(void)
{
  char* str = NULL;
  GetMemory(&str);//址传递
  strcpy(str, "hello world");
  printf(str);
  free(str);
  str = NULL;
}
int main()
{
  Test();
  return 0;
}

运行结果

hello world

这个问题,在日后会经常遇到,需要留意一下。

练习2:

char* GetMemory(void)
{
  char p[] = "hello world";
  return p;
}
void Test(void)
{
  char* str = NULL;
  str = GetMemory();
  printf(str);
}

运⾏会有什么样的结果?

数组p是一个局部变量

在 GetMemory 函数之后,数组 p 的内存空间就被销毁了,还给了操作系统,虽然把这个数组首元素的地址返了回去,但此时再通过地址去访问这一块空间,就成了非法访问。

修改后的代码

char* GetMemory(void)
{
  char* p = "hello world";
  return p;
}
void Test(void)
{
  char* str = NULL;
  str = GetMemory();
  printf(str);
}
int main()
{
  Test();
  return 0;
}

运行结果

hello world

练习3:

void GetMemory(char **p, int num)
{
*p = (char *)malloc(num);
}
void Test(void)
{
char *str = NULL;
GetMemory(&str, 100);
strcpy(str, "hello");
printf(str);
}

运行结果

hello world

这段代码运行后发现是可以的,但是看到了malloc却看不到free,存在内存泄漏问题

修改后的代码

void GetMemory(char** p, int num)
{
  *p = (char*)malloc(num);
}
void Test(void)
{
  char* str = NULL;
  GetMemory(&str, 100);
  strcpy(str, "hello");
  printf(str);
  free(str);
  str = NULL;
}
int main()
{
  Test();
  return 0;
}

练习4:

void Test(void)
{
char *str = (char *) malloc(100);
strcpy(str, "hello");
free(str);
if(str != NULL)
{
strcpy(str, "world");
printf(str);
}
}

运⾏会有什么样的结果?

world

代码也是可以运行的

但是依然有错

因为早在开始,就把str给释放了,这块内存权限给了操作系统

在 free 完后没有把 str 置为空,所以 str 还是指向那块空间,此时的 str 已经变成了一个野指针,后面一些列涉及 str 的操作都属于非法访问。

修改后的代码

void Test(void)
{
  char* str = (char*)malloc(100);
  strcpy(str, "hello");
  free(str);
  str = NULL;
  if (str != NULL)
  {
    strcpy(str, "world");
    printf(str);
  }
}


目录
相关文章
|
2天前
6个常见的动态内存的错误和动态内存经典笔试题
6个常见的动态内存的错误和动态内存经典笔试题
|
2天前
动态内存管理题目讲解
动态内存管理题目讲解
|
2天前
|
存储 程序员 编译器
动态内存管理+柔性数组+经典笔试题
动态内存管理+柔性数组+经典笔试题
46 0
|
6月前
|
程序员 C语言 C++
动态内存管理之经典笔试题
动态内存管理之经典笔试题
59 0
|
6月前
|
编译器 C语言 C++
C进阶-动态内存管理+柔性数组(2)
C进阶-动态内存管理+柔性数组
36 0
|
6月前
C进阶-动态内存管理+柔性数组(1)
C进阶-动态内存管理+柔性数组
25 0
|
6月前
|
安全 编译器
【C进阶】动态内存管理
【C进阶】动态内存管理
26 0
【C进阶】动态内存管理
|
8月前
|
存储 编译器 C语言
【C++初阶】动态内存管理
【C++初阶】动态内存管理
102 0
【经典笔试题】动态内存管理
test1:请问执行上面代码,会出现什么结果? 解析:运行该段代码时,程序会崩溃 答案:调用Test函数时,在Test函数内部又调用Getmemory函数,即使在Getmemory函数内部申请空间,返回的该空间的起始地址给p,然而p并未返回,str仍为NULL。拷贝 "hello world"到str内部,将会导致程序崩溃。 改正:可以将p申请的空间返回。
|
11月前
|
存储 编译器 C语言
【C语言进阶】动态内存管理详解与常见动态内存错误以及柔性数组使用与介绍
【C语言进阶】动态内存管理详解与常见动态内存错误以及柔性数组使用与介绍