zoukankan      html  css  js  c++  java
  • 【c++】指针参数是如何传递内存的

    参数策略

    如果函数的参数是一个指针,不要指望用该指针去动态申请内存。如下:

    void GetMemory(char *p, int num)
    {
        p = (char *)malloc(sizeof(char) * num);
    }
    void Test(void)
    {
        char *str = NULL;
        GetMemory(str, 100);     //str仍未NULL
        strcpy(str, "hello");    //运行错误
    }

    原因是编译器总是为每个参数制作临时副本。指针参数p, 其副本为_p,使_p=p。如果改变了_p所指的内容,相应的p所指的内容也跟着改变(毕竟指向同样的地方)。但是在GetMemory中动态分配内存空间,改变了_p的内容。在调用函数中的p还是指向NULL。再者,因为函数GetMemory中动态分配了空间,但是没释放,这样调用一次函数,就泄露了一次内存。图示:

    如果非得用指针参数申请内存,可以用指针的指针作为参数申请内存

    void GetMemory(char **p, int num)
    {
        *p = (char *)malloc(sizeof(char) * num);
    }
    void Test(void)
    {
        char *str = NULL;
        GetMemory(&str, 100);     //记得加地址符
    strcpy(str, "hello");
    free(str) }

    原理是一样的,比较难理解,图示表示:

    比较好的方法是传指针的引用

    #include <iostream>
    #include <string>
    #include <cstring>
    #include <cstdlib>
    using namespace std;
    void GetMemory(char *&p, int num)
    {
        p = (char *)malloc(sizeof(char) * num);
    }
    
    void Test(void)
    {
        char *str = NULL;
        GetMemory(str, 100);
        strcpy(str, "hello");
        cout << str << endl;
        free(str);
    }
    int main()
    {
        Test();
    }

     这里注意指针的引用 为char* &a,要是不好理解可以这样:

        typedef char* pchar;
        pchar &a

    返回值策略

    可以用函数返回值来传递动态内存。这中方法比“指针的指针”简单多了

    char *GetMemory(int num)
    {
         char *p = (char *)malloc(sizeof(char) * num);
         return p;
    }
    void Test(void)
    {
        char *str = NULL;
        str = GetMemory(100);  //str指向了动态分配的空间
        strcpy(str, "hello"); 
        free(str)
     }

    在使用返回值时,千万别返回指向“栈内存”的指针、引用,因为该内存在函数结束时自动消亡了,返回的指针是个野指针了。例如

    char *GetString()
    {
         char p[] = "hello world"; //数组内容存储在栈区,函数结束时,会释放掉
         return p;
    }
    void Test(void)
    {
        char *str = NULL;
        str = GetString();      //因为非配的内存早已释放掉,此时的str是个野指针,内容是垃圾
       cout << str << endl;
     }

    在函数中不定义数组,定义指针,示例:

    char *GetString()
    {
         char *p = "hello world"; //数组内容存储在静态区,函数结束时,不会释放掉
         return p;
    }
    void Test(void)
    {
        char *str = NULL;
        str = GetString();      
        cout << str << endl;
     }

    此时的程序是正确的,但是有一点,此时分配的内存处于静态区,是只可以读取但是不可以修改的。

  • 相关阅读:
    .NET Core采用的全新配置系统[4]: “Options模式”下各种类型的Options对象是如何绑定的?
    .NET Core采用的全新配置系统[3]: “Options模式”下的配置是如何绑定为Options对象
    .NET Core采用的全新配置系统[2]: 配置模型设计详解
    .NET Core采用的全新配置系统[1]: 读取配置数据
    ASP.NET Core 运行原理解剖[5]:Authentication
    kubernetes-dashboard(1.8.3)部署与踩坑
    使用kubeadm搭建Kubernetes(1.10.2)集群(国内环境)
    Docker初体验
    ASP.NET Core Logging in Elasticsearch with Kibana
    ASP.NET Core 认证与授权[7]:动态授权
  • 原文地址:https://www.cnblogs.com/kaituorensheng/p/3246900.html
Copyright © 2011-2022 走看看