c++用参数返回堆上的空间

    添加时间:2013-7-26 点击量:

    《高质量c++和c编程》7.4 指针参数是如何传递内存的一节中写道



    void GetMemory(char p, int num) 
    
    {
    p
    = (char )malloc(sizeofchar num);
    }
    void Test(void
    {
    char str = NULL;
    GetMemory(str,
    100); // str 仍然为 NULL
    strcpy(str, hello); // 运行错误
    }


    无法返回内存,可以用如式格式



    void GetMemory2(char p, int num) 
    
    {
    p = (char )malloc(sizeofchar num);
    }
    void Test2(void
    {
    char str = NULL;
    GetMemory2(
    &str, 100); // 重视参数是 &str ,而不是str
    strcpy(str, hello);
    cout
    << str << endl;
    free(str);
    }


    小我的懂得就是,实际上指针传递仍然是一种值传递,只不过在参数是指针的时辰,传递的是指针的副本,如许你在地址上的操纵实际就反应到了内存中,举个例子来说,假设有一个函数



    void fun(int  p)
    
    {
    p
    = new int;
    }


    当用调用时fun(q),会产生实参的一个副本设为_p,函数体为副本_p分派了内存,实际上并未改变实参p,这就是GetMemory没有成功的原因。相反,若是我们有如下函数



    void fun(int p)
    
    {
    p = 3;
    }


    在这个函数中,当产生实参调用的时辰,仍然会产生实参的副本,然则重视这里不是改变副本,而是改变副本指向的内存中的内容,这里p是一个整形指针,在内存中占四个字节,副本和实参指向同一片内存,所以当你


    在以副本为地址的内存内赋值3,实际也就是改变了实参指向的内存中的内容。


    总结一下就是:指针传递仍然是值传递,所以我们在函数体内只有操纵p才会达到我们的指针传递请求,而不是操纵p,如许操纵只在副本上,实际并不反应到实参指向的内存。


    书中另一种办法是:



    char GetMemory3(int num) 
    
    {
    char p = (char )malloc(sizeof
    return p;
    }
    void Test3(void
    {
    char str = NULL;
    str
    = GetMemory3(100);
    strcpy(str,
    hello);
    cout
    << str << endl;
    free(str);
    }


    实际是将堆的特点和return相连络,堆上分派的内存在函数不会开释,而return实际返回的p的一个副本,然则这里的副本是一个指针,简单的说是一个内存地址,而这个地址在函数停止后并没有开释,所以,我们可以持续


    应用。若是是通俗的局部变量,return返回它的一个副本,随后局部变量跟着函数的停止而被开释,这在某些时辰会引起麻烦,比如



    char GetString(void
    {
    char p[] = hello world;
    return p; // 编译器将提出警告
    }
    void Test4(void
    {
    char str = NULL;
    str
    = GetString(); // str 的内容是垃圾
    cout<< str << endl;
    }


    至于return似乎还有器材说,一时想不起。。。


    工作总有例外,今天小妞找我调试法度,发了然一件很独特的工作,看代码



    void getArray(char s, int N)
    
    {
    std::ifstream
    intest.txt);
    if (!in.is_open())
    {
    std::cout
    <<error<<std::endl;
    }
    int i = 0;
    while(i < N)
    {
    s[i]
    = (char)malloc(sizeofchar100);
    in.getline(s[i], 100);
    ++i;
    }
    in.close();

    }
    int main()
    {
    char s = (char )malloc(sizeofchar4);
    getArray(s,
    4);
    forint i=0; i<4; i++
    {
    std::cout
    <<s[i]<<std::endl;
    }
    return 0;
    }


    这个法度可以正确编译履行。而下面代码



    void getArray1(char s, int N)
    
    {
    // s = (char )malloc(sizeof(char) 4);
    s = new char[4];
    std::ifstream
    intest.txt);
    if (!in.is_open())
    {
    std::cout
    <<error<<std::endl;
    }
    int i = 0;
    while(i < N)
    {
    // s[i] = (char)malloc(sizeof(char)100);
    s[i] = new char[100];
    in.getline(s[i], 100);
    ++i;
    }
    in.close();

    }


    int main()
    {
    char s;
    getArray1(s,
    4);
    forint i=0; i<4; i++
    {
    std::cout
    <<s[i]<<std::endl;
    }
    return 0;
    }


    这个代码确切在运行时失足


    解析了一下,小我认为固然两个函数的参数都是char s,然则一个在main()中先分派,一个直接在getArray平分派,原因就在于此,getarray函数在main函数中先分派了内存,然后传递给它,固然仍然是值传递,然则


    s的元素是指针,getarray函数中在main函数分派的内存上完成了操纵,所以当函数停止时,所有操纵仍然保存下来。getarray1函数不合,它是在函数体内完全分派内存,然后施加操纵的,相当于都在副本上,所有操纵都不会


    在函数停止后保存下来。


    这是小我的一点懂得,如有不合错误的处所还请指教。

    我俩之间有着强烈的吸引力。短短几个小时后,我俩已经明白:我们的心是一个整体的两半,我俩的心灵是孪生兄妹,是知己。她让我感到更有活力,更完美,更幸福。即使她不在我身边,我依然还是感到幸福,因为她总是以这样或者那样的方式出现在我心头。——恩里克·巴里奥斯《爱的文明》
    分享到: