zoukankan      html  css  js  c++  java
  • 指针参数是如何传递内存的(转载)

    参数策略

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

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

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

    指针形参感悟:

    (1)想修改指针指向空间的内容,传指针
    (2)你想修改指针的指向,传指针的指针

    转载自:http://www.cnblogs.com/kaituorensheng/p/3246900.html

  • 相关阅读:
    SAP S/4HANA extensibility扩展原理介绍
    SAP CRM系统订单模型的设计与实现
    使用nodejs代码在SAP C4C里创建Individual customer
    SAP Cloud for Customer Account和individual customer的区别
    Let the Balloon Rise map一个数组
    How Many Tables 简单并查集
    Heap Operations 优先队列
    Arpa’s obvious problem and Mehrdad’s terrible solution 思维
    Passing the Message 单调栈两次
    The Suspects 并查集
  • 原文地址:https://www.cnblogs.com/kimiway/p/3991731.html
Copyright © 2011-2022 走看看