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


    在这里插入图片描述

    前言

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

    请添加图片描述

    练习1:

    void GetMemory(char* p)
    {
    	p = (char*)malloc(100);
    }
    void Test(void)
    {
    	char* str = NULL;
    	GetMemory(str);
    	strcpy(str, "hello world");
    	printf(str);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    运⾏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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    运行结果

    hello world
    
    • 1

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

    练习2:

    char* GetMemory(void)
    {
    	char p[] = "hello world";
    	return p;
    }
    void Test(void)
    {
    	char* str = NULL;
    	str = GetMemory();
    	printf(str);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    运⾏会有什么样的结果?
    数组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;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    运行结果

    hello world
    
    • 1

    练习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);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    运行结果

    hello world
    
    • 1

    这段代码运行后发现是可以的,但是看到了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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    练习4:

    void Test(void)
    {
    char *str = (char *) malloc(100);
    strcpy(str, "hello");
    free(str);
    if(str != NULL)
    {
    strcpy(str, "world");
    printf(str);
    }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    运⾏会有什么样的结果?

    world
    
    • 1

    代码也是可以运行的

    但是依然有错

    因为早在开始,就把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);
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    在这里插入图片描述

  • 相关阅读:
    Java Base64 加密与解密
    protolator简介
    C语言系列之指针与数组
    低资源方面级情感分析研究综述
    语言模型的发展
    安装新操作系统需要注意的问题
    OA系统源码
    [Linux入门]---文本编辑器vim使用
    what is flinksql hint?
    回顾C++
  • 原文地址:https://blog.csdn.net/weixin_73397765/article/details/133976924