• C语言 子函数调malloc申请内存返回给主函数使用——可行,但要注意


    一般情况,子函数中动态申请内存,将地址返回给主函数,理论上应该也是可以的,需要子函数返回动态内存地址,主函数实参是相应的地址变量即可。只不过,主函数实参传入子函数之前,可能会将指针置空,那么,子函数就不能动态申请内存了。

    如下例子:

    C语言进阶---动态内存管理_c语言怎么遍历动态申请里面的内容-CSDN博客

    4.几个经典的面试题

    4.1 题目1:
    1. void Getmemory(char* p)//形参是实参的一份临时拷贝 p是指针变量 p指向NULL *p是NULL
    2. {
    3. p = (char*)malloc(100);//p由指向NULL 变为指向malloc开辟空间的起始地址
    4. }
    5. void Test(void)
    6. {
    7. char* str = NULL;
    8. GetMemory(str);//传的是实参
    9. strcpy(str, "helllo world");
    10. printf(str);
    11. }
    12. //程序会崩溃无法打印

    更正:通过传实参的地址来找到实参在内存当中的位置然后再改变实参的值:

    1. void GetMemory(char** p)//char**p接收str的地址,是一个二级指针
    2. {
    3. *p = (char*)malloc(100);//*p==str 由指向NULL 变为指向malloc开辟空间的起始地址
    4. }
    5. void Test(void)
    6. {
    7. char* str = NULL;
    8. GetMemory(&str);//转str的地址
    9. strcpy(str, "helllo world");
    10. printf(str);
    11. free(str);
    12. str = NULL;
    13. }
    14. int main()
    15. {
    16. Test();
    17. return 0;
    18. }
    19. //程序会正常打印"hello world"

    另一个传地址的例子:

    4.2题目2:

    返回栈空间问题:

    1. char* GetMemory(void)
    2. {
    3. char p [] = "hello world";//栈空间开辟数组
    4. return p;//p放在寄存器当中,这个函数可以成功返回数组名p,也就是数组的首元素地址
    5. }
    6. void Test(void)
    7. {
    8. char* str = NULL;
    9. str = GetMemory();
    10. printf(str);
    11. }
    12. int main()
    13. {
    14. Test();
    15. return 0;
    16. }
    17. //栈空间在用完之后会被系统回收,因此创建的数组p在GetMemory调用完之后就已经被销毁无法使用了
    18. //str属于是野指针去访问了一块被销毁的空间,因此会打印一些随机值

    改为:

    1. int* test()
    2. {
    3. int a = 10;
    4. return &a;//a的地址被存放在寄存器当中
    5. }
    6. int main()
    7. {
    8. int* p = test();//p接收到a的地址
    9. printf("%d\n", *p);//p已经是野指针 打印10 因为调用test的栈空间还没有被覆盖
    10. printf("%d\n", *p);// 打印随机值 有一次调用test函数,栈空间被新随机值给覆盖
    11. return 0;
    12. }

    另外,上面所说子函数动态申请内存给主函数用,主函数在使用完要释放。释放后最好置空,否则,其是个野指针,可能会导致错误。

    4.3题目3:
    1. void GetMemory(char** p, int num)
    2. {
    3. assert(*p);
    4. *p = (char*)malloc(num);
    5. }
    6. void tset(void)
    7. {
    8. char* str = NULL;
    9. GetMemory(&str, 100);
    10. strcpy(str, "hello");
    11. printf(str);
    12. //free释放
    13. free(str);
    14. str = NULL;
    15. }
    16. int main()
    17. {
    18. test();
    19. return 0;
    20. }

    改正:

    1. void test(void)
    2. {
    3. char* str = (char*)malloc(100);
    4. strcpy(str, "hello");
    5. free(str);//free释放
    6. str = NULL;//置空
    7. if (str != NULL)
    8. {
    9. strcpy(str, "world");
    10. printf(str);//无法打印
    11. }
    12. }
    13. int main()
    14. {
    15. test();
    16. return 0;
    17. }

  • 相关阅读:
    Python网络爬虫库:轻松提取网页数据的利器
    Hive学习笔记2
    动态规划基础
    识别热点事件/热点新闻(图搜索算法/度中心性算法)
    单片机——将P1口状态送入P0、P2和P3口
    紧固螺栓的常见类型有哪些?
    Electron:窗口、窗口标题和边框
    几款实用的照片变漫画免费软件,千万别错过
    SUSE 发布 NeuVector 5.0,从数据中心、云端到边缘全面拓展云原生安全能力
    基于Java+Vue前后端分离乐购游戏商城系统设计实现(源码+lw+部署文档+讲解等)
  • 原文地址:https://blog.csdn.net/weixin_40194697/article/details/134539546