C++内存管理和模版

文章详细阐述了C++中变量在内存的分布,包括全局变量、静态变量、局部变量和动态分配的内存。讨论了new、delete、malloc、free的内存管理机制及区别,并举例说明了如何使用。此外,还介绍了模板在泛型编程中的应用,展示了如何创建和使用模板函数及模板类。
摘要由CSDN通过智能技术生成

 变量所在哪个内存区域以及变量所占空间大小

int globalVar = 1;//数据段(静态区)
static int staticGlobalVar = 1;//数据段(静态区)
void Test()
{
static int staticVar = 1;//数据段(静态区)
int localVar = 1;    //栈
int num1[10] = {1, 2, 3, 4};    //栈
char char2[] = "abcd";    //char2 *char2 在"栈"中
const char* pChar3 = "abcd";    //pChar在"栈"中,*pChar在"代码段(常量区)"
int* ptr1 = (int*)malloc(sizeof (int)*4);    //ptr1在"栈"中 *ptr1在"堆"中
int* ptr2 = (int*)calloc(4, sizeof(int));
int* ptr3 = (int*)realloc(ptr2, sizeof(int)*4);
free (ptr1);
free (ptr3);
}

所在内存区:

        golobalVar、staticGlobalVar、staticVar都是在“数据段(静态区)”中,因为前两个是全局变量,全局变量都在静态区,后面一个是static静态类型,也在静态区。

        普通的变量localVar和数组num1函数结束后释放,都在“栈”中;数组char2[]只是动态大小,初始化完成后和num1一样在“栈”中;*char2也在“栈”中,char2[]在栈中开辟了5个字节,把常量“abcd”拷贝过去,所以*char2是栈中的“a”。

        pChar3是局部指针变量,在“栈”中,又因为pChar3指向的是常量区“abcd”,所以*pChar3在“代码段(常量区)”。

        ptr1,ptr2,ptr3都是局部指针变量,都是在“栈”上,*ptr1指向的空间是在“堆”上开辟的。

所占空间大小:

sizeof(num1) = 40;  

sizeof(char2) = 5;   strlen(char2) = 4;

sizeof(pChar3) = 4或8  //根据系统可能是4可能是8;   

strlen(pChar3) = 4;

sizeof(ptr1) = 4或8;

申请动态空间new/delete

malloc/free和new/delete的共同点是:都是从上申请空间,并且需要用户手动释放。不同的地方是:

        1. malloc和free是函数,new和delete是操作符

        2.malloc申请的空间不会初始化,new可以初始化

        3.malloc申请空间时,需要手动计算空间大小并传递,new只需在其后跟上空间的类型即可,如果是多个对象,[]中指定对象个数即可

        4. malloc的返回值为void*,在使用时必须强转,new不需要,因为new后跟的是空间的类型

        5.malloc申请空间失败时,返回的是NULL,因此使用时必须判空,new不需要,但是new需要捕获异常

        6.申请自定义类型对象时,malloc/free只会开辟空间,不会调用构造函数与析构函数,而new在申请空间后会调用构造函数完成对象的初始化,delete在释放空间前会调用析构函数完成空间中资源的清理

        7.malloc和free,new和delete最好配套使用,不然会有意想不到的错误

#include <iostream>
using namespace std;
class A
{
public:
    A(int a=0)
        :_a(a)//初始化列表
    {
        cout<< "A()" <<endl;
    }
    ~A()
    {
        cout<< "~A()" <<endl;
    }
private:
    int _a;
};

int test1()//动态空间 new
{
    int* p1=new int;    //申请一个int不会初始化
    int* p2=new int(20);//一个int初始化为20
    int* p3=new int[10];//申请10个int的数组
    int* p4=new int[10]{1,2,3};//数组初始化
    delete p1;//free p1
    delete p2;//
    delete[] p3;//free数组p3 p4
    delete[] p4;

    //new/delete和malloc/free的区别就是new/delete会调用构造和析构函数
    A* a1=new A();  //调用构造函数
    delete a1;      //先调用析构函数 再释放空间

    A* a2=new A[3]; //调用3次构造函数
    delete[] a2;    //先调用析构函数 再释放空间

    A* a3=(A*)malloc(sizeof(A));
    if(a3== nullptr) perror("malloc fail");
    new(a3)A(20);//定位new 初始化已有空间
    a3->~A();
    free(a3);

    return 0;
}

泛型编程--模版

        模版是让编译器去产生特定类型函数的模具,Debug过程中看似用的是一个函数,实则汇编中用的是编译器产生的对应类型的函数

        格式:template<typename 自定义名1 , typelate 自定义名2 , ......>,也可以使用class代替typename

定义过template后只有第一个函数生效模版。

        显示实例化:当一个函数中要用两个不同类型的实参:

函数名<类型>(实参1 , 实参2 , ....)

//template<class T>
template<typename T>
void Swap(T& x,T& y)
{
    T tmp=x;
    x=y;
    y=tmp;
}

template<typename A>
A ADD(const A& x,const A&y)
{
    return x+y;
}
int test2()//泛型编程--模版
{
    //模版是让编译器去产生特定类型函数的模具
    int a=10,b=20;
    Swap(a,b);//看似是用同一个函数,汇编中用的不是一个
    double c=30,d=40;
    Swap(c,d);

    cout << ADD(a,b) << endl;
    cout << ADD(c,d) << endl;
    //显示实例化
    cout << ADD<int>(a,c) << endl;
    cout << ADD<double>(d,b) << endl;
    
    return 0;
}

类也可以使用模版

template<class S>
class Stack
{
public:
    Stack(int capacity=4)
    {
        _a=new S[capacity];
        _top=_capacity=0;
        cout<< "Stack()" << endl;
    }
    ~Stack()
    {
        delete[] _a;
        _capacity=_top=0;
        cout<< "~Stack()" << endl;
    }
private:
    S* _a;
    size_t _top;
    size_t _capacity;
};
int test3()//显示实例化--不同类型栈
{
    Stack<int> st1;
    Stack<double> st2;
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值