C++之函数返回局部变量的初级探索---补充(3)《Effective C++》

我们说C++的内存结构为栈,堆,全局变量域,其中全局变量域中存放global变量,static变量和常量,栈中存放运行时候的函数以及局部变量,堆中存放程序中用new生成的对象,那么程序的函数返回的局部变量与C++的内存分配有什么关系呢?下面请看如下代码,对比思考:

a.cpp

#include <iostream>
#include <string>
using namespace std;
class Hello{
public:
    Hello(){

    }
    Hello(int x, int y) :x(x), y(y){

    }
    Hello(Hello& h){
        this->x = h.x;
        this->y = h.y;
    }
    Hello& operator=(const Hello& h){
        this->x = h.x;
        this->y = h.y;
        return *this;
    }
    friend ostream& operator<<(ostream& os, Hello& hel){
        os << hel.x << " " << hel.y << endl;
        return os;
    }
    void show(){
        cout << x << " " << y << endl; 
    }

    friend Hello* createHello(Hello& hello){
        try{
            Hello *hel = new Hello();
            hel->x = hello.x;
            hel->y = hello.y;
            return hel;
        }
        catch (exception &e){
            cout << e.what() << endl;
        }
        return NULL;
    }
    ~Hello(){

    }
private:
    int x;
    int y;
};

int* h1(){
    int m = 9;
    return &m;
}
int main(){
    Hello h1(10, 10);
    Hello *h2 = createHello(h1);
    cout << *h2 << endl;
    delete h2;
    return 0;
}

运行结果为:
这里写图片描述
代码变更呢?结果会怎样呢?

a2.cpp

#include <iostream>
#include <string>
using namespace std;
class Hello{
public:
    Hello(){

    }
    Hello(int x, int y) :x(x), y(y){

    }
    Hello(Hello& h){
        this->x = h.x;
        this->y = h.y;
    }
    Hello& operator=(const Hello& h){
        this->x = h.x;
        this->y = h.y;
        return *this;
    }
    friend ostream& operator<<(ostream& os, Hello& hel){
        os << hel.x << " " << hel.y << endl;
        return os;
    }
    void show(){
        cout << x << " " << y << endl; 
    }

    friend Hello* createHello(Hello& hello){
        try{
            Hello temp(hello);
            return &temp;
        }
        catch (exception &e){
            cout << e.what() << endl;
        }
        return NULL;
    }
    ~Hello(){

    }
private:
    int x;
    int y;
};

int* h1(){
    int m = 9;
    return &m;
}
int main(){
    Hello h1(10, 10);
    Hello *h2 = createHello(h1);
    cout << *h2 << endl;
    delete h2;
    return 0;
}

结果如下:
这里写图片描述
我们可以很清楚的看到,此时这个程序返回的值是随机数,并不是我们想要的,那么问题处在哪里呢?

经过对比,可以发现a.cpp中我们创建了一个临时对象Hello *hel,hel指向new 在堆中分配的地址,当函数结束时候,局部变量为hel指针而已,被返回保存到主程序中的寄存器中,函数中的hel指针被销毁而已,创建的对象仍旧在堆中,因此当我们访问的时候,可以找到堆中的信息,然后加以输出,最后通过delete hel销毁掉堆中的对象,很通顺的一个过程;

a2.cpp中我们通过copy构造函数创建了一个Hello temp临时变量,这个对象的全部都在函数栈中,由于有析构函数,在结束函数调用的时候,临时对象被销毁,主程序的寄存器中保留了一个指针,指向的那个对象已经被析构函数销毁,因此访问的时候找不到所以出现随机数! 有朋友问按照这个思路的话,这个问题怎么解?

int* h1(){
    int m = 9;
    return &m;
}
int& h2(){
    int m = 9;
    return m;
}
int main(){
    int* h1_ptr=h1();
    int hh2=h2();
    cout << *h1_ptr << endl;
    hh2 = 100;
    cout << hh2 << endl;
    return 0;
}

运行结果为:

什么鬼
相同的问题也适用于全局变量域,效果如下:

char *h2(){
    int m = 9;
    char s[] = "hello";
    return s;
}
int main(){
    char *s = h2();
    cout << s << endl;

    return 0;
}

运行结果:
这里写图片描述

char *h2(){
    int m = 9;
    char s[] = "hello";
    return s;
}
int main(){
    char *s = h2();
    cout << s << endl;

    return 0;
}

运行结果:
这里写图片描述

可以看到,竟然局部变量的值没有被销毁,什么鬼?哈哈,不要纠结啦,兄弟,

因为这些局部变量都是基本类型,没有析构函数,程序在执行栈顶的时候没有执行别的栈操作,因此这些变量值暂时还在栈中,其实是编译器懒得彻底销毁,在别的栈操作未执行时,而基本类型没有析构函数,编译器就想偷个懒,暂时让其存在一下,直到有新的栈操作发生时候才覆盖,因此,不要太纠结呀

,祝大家在C++的大坑中越走越顺!!!路漫漫兮其修远兮,吾将上下而求索!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值