C++:程序的内存分区模型、new操作符、引用

发布时间:2024年01月09日

目录

1、内存分区模型

内存四区的意义:

程序运行前

程序运行后

2、new操作符

3、引用

引用的注意事项

引用做函数参数

引用做函数返回值

引用的本质


参考:http://t.csdn.cn/Tlpkp

1、内存分区模型

C++程序在执行时,将内存大方向划分为4个区域

  • 代码区:存放函数的二级制代码,由操作系统进行管理的

  • 全局区:存放全局变量和静态变量以及常量

  • 栈区:由编译器自动分配释放,存放函数的参数值,局部变量等

  • 堆区: 由程序员分配和释放,若程序员不释放,程序结束时由操作系统回收

内存四区的意义:

内存四区意义:不同区域存放的数据,赋予不同的声明周期,给我们更大的灵活编程

程序运行前

在程序编译后,生成了exe可执行文件,未执行该程序前分为两个区域。

代码区:

存放cpu执行的机器指令 代码区是共享的,共享的目的是对于频繁被执行的程序,只需要在内存中有一份打码即可 代码区是只读的,使其只读的原因是防止程序意外的修改了它的指令 全局区:

全局变量和静态变量存放于此 全局区还包含了常量区,字符串常量和其他常量也存放于此 该区域的数据在程序结束之后由操作系统释放

程序运行后

栈区:

由编译器自动分配释放,存放函数的参数值,局部变量等。 注意事项:不要返回局部变量的地址,栈区开辟的数据由编译器自动释放 堆区:

有程序员分配释放,若程序员不释放,程序结束之后有操作系统回收 在C++中主要利用new在堆区中开辟内存

2、new操作符

作用:在堆区开辟数据。堆区开辟的数据,由程序员手动开辟,手动释放,释放用delete。

语法:

new 数据类型;

利用new创建的数据,会返回该数据对应类型的指针

new 数据类型
//函数 在堆区开辟空间
int * func()
{
    int *p =new int(10); //小括号里的数是赋值
    return p;
}
//在堆区开辟一个数据
void test_01()
{
    int *p=func();
    cout<< *p <<endl;
    //释放堆区数据
    delete p;
}
//在堆区利用new开辟数组
void test_02()
{
    //创建一个10个整形数据数组
    int *p = new int[10]; //10代表数组有10个数据
    //释放堆区数组,释放数组要加[]
    delete[] p; 
}

3、引用

引用的基本作用:给变量取别名

基本语法:

数据类型 &别名 = 原名;
//示例
int main()
{
  int a=10; //变量名:a
  int &b=a; //取别名: b
  cout<<"a="<<a<<endl;
  cout<<"b="<<b<<endl;
  b=100; //通过别名也能修改变量数值
  cout<<"a="<<a<<endl;
  cout<<"b="<<b<<endl;
  system("pause");
  return 0;
}

引用的注意事项

  • 引用必须初始化

  • 引用在初始化后,不可以更改

int main (){
    int a=10; int b=20;
    //int &c; //错误,引用必须初始化
    int &c =a;//一旦初始化,就不可以更改
    c=b; //赋值操作
    system("pause");
    return 0;
}

引用做函数参数

作用:函数传参时,可以利用引用的技术让形参修饰实参

优点:可以简化指针修改实参(传址)

void changeNums(int &a,int& b);//引用传递
{
    int temp = a;
    a=b;
    b=temp;
}
int main(void)
{
    int a = 10;
    int b = 20;
    changeNums(a,b);
    //引用——其实上面的a就是下面a的一个别名
    return 0;
}

引用做函数返回值

作用:引用时可以做函数返回值存在的

注意:不要返回局部变量引用

用法:函数调用作为左值

//返回局部变量引用 ,不要这么操作
int& test01{
    int a =10;//栈区
    return a;
}

//返回静态变量引用
int& test02{
    static int a =20;//静态变量存放在全局区,全局区的数据在程序结束后系统释放
    return a;
}

int main(){
    //局部变量:存放在栈区,代码执行结束后自动释放
    int &ref =test01(); // a取别名=ref
      cout << ref << endl;//第一次结果正确是因为编译器做了保留
    cout << ref << endl;//第二次结果错误是因为a的内存已经释放

    //作为左值
    test2() = 1000;//如果函数的返回值是引用,这个函数调用可以作为左值
    cout << ret2 << endl;

    system("pause");
    return 0;
}

引用的本质

本质:引用的本质在c++内部实现是一个指针常量,引用一旦被初始化之后就不能更改。

void func(int& ref)
{
    ref = 100;//ref是引用,转换为*ref = 100
}
int main(void)
{
    int a  = 10;
    int &ref = a;//自动转化int* const ref = &a;//指针常量是指针指向不可改,也说明为什么引用不可更改
    ref =20;//自动发现ref是引用,自动转换为*ref = 20;
}

结论:C++推荐使用引用技术,因为语法方便,引用本质是指针常量,但所有的指针操作编译器都帮我们做了。

文章来源:https://blog.csdn.net/Mr_dffan/article/details/131407110
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。