c和c++的区别(三)-----动态内存申请的区别

动态内存申请的区别

c语言的动态内存申请-->由函数申请

  • malloc():不带初始化的

  • calloc():带初始化的,初始化为0

  • realloc():重新申请(在原内存的后面接着申请)

  • free(): 释放

c++的动态内存申请-->由关键字申请

  • 只有new(申请)和delete(释放)

  • 单个变量内存申请

  • 数组的动态内存申请

  • 结构体的动态内存申请

单个变量的内存申请

申请单个内存不做初始化

void testOneMemory()
{
//申请一个整型变量的内存,不做初始化,让指针指向一个变量的内存
    int*pInt=new int;     //申请完内存后,可以当变量来使用
    *pInt=123;
    cout<<*pInt<<endl;    //输出123
}

可以new其他类型,只要注意格式即可

void testOneMemory()
{
//申请一个字符型变量的内存,不做初始化,让指针指向一个变量的内存
    char* pChar=new char;   //申请完内存后,可以当变量来使用
    *pChar='a';
    cout<<*pChar<<endl;     //输出a
}

申请单个内存时做初始化

//用()可以给单个数据初始化
void testOneMemory()
{
    int*pNum=new int(124);  //用()给当前申请的整型变量的内存初始化为124
    cout<<*pNum<<endl;      //输出124
}

单个变量的内存释放

    delete pInt;
    pInt=nullptr;     /*释放后一定要置空,否则指针还是存在,指针指向新的内存还能使用
                        释放没有置空可以再new一段内存,相当于改变指向*/
    pInt=new int;
    *pInt=33;
    cout<<*pInt<<endl;//new完后还要做一次释放|置空

如何申请一大串内存?用一维数组方式申请

用一维数组方式申请一大串内存不做初始化

void testArrayMemory()
{
    //申请一段内存用一维数组方式申请|等效产生了int pInt[3]的数组
    int*pInt=new int[3];   /*[]中代表长度,可以是常量|变量,只要是值就可以了
                             'A'也可以,自动转换成65*/
    delete pInt;    //这样释放也可以,推荐用下一行代码的方式,增加可读性

    delete pInt[];  //用了[]代表当前这个变量是一段内存

    pInt[]=pstr;    //释放完后置空        
}

也可以让用户输入长度

    int num=0;
    cin>>num;
    int* pInt=new int[num];

用字符串处理用strcpy的方式

#include<cstring>                   //c语言的string
int main()
{
    char* pstr=new char[15];        //char* 不能直接赋值
    strcpy(pstr,"i love you");      //处理字符串通常用拷贝的方式
//strcpy_s(pstr,15,"ILoveYou");     增强版
    cout<<pstr<<endl;               //输出ILoveYou

}
  • char* 不能直接赋值,处理字符串尽量用strcpy的方式

  • "i love you"是指向常量区的内存,没有赋值到堆区上

#include<cstring>       
int main()
{
    char* pstr=new char[15]; //ptr 不建议直接赋值,这样写数据没有赋值到new char[15]上
    pstr="i love you";       /*vs2013这样写不报错,vs2019会报错:const char* 类型的值
                               不能用于初始化char* 类型的实体*/
                             //解决方案:const char* pstr=new char[15];   
    cout<<pstr<<endl;
} 
  • new char[15](堆区)上没有任何数据,这段内存没有初始化,输出乱码
  • 把pstr的指向改变了,不影响pstr申请的内存

#include<cstring>
int main()
{
    const char* pstr=new char[15];     //pstr指向new char[15]
    const char*pstr1=pstr;             //pstr1指向pstr,指向同一块内存ptr
    pstr="i love you";                 //pstr改为指向"i love you"
    cout<<pstr<<endl;                  //输出:i love you
    cout<<pstr1<<endl;                 //pstr1未做初始化,没有数据,输出乱码
}

用一维数组方式申请一串内存时做初始化- - -一堆数据用{ }的方式

//用{ }可以给一段内存初始化,未初始化的参数默认为0
void testArrayMemory()
{
    int*pNum=new int[3]{1,2,3};        
    for(int i=0;i<3;i++)
    {                     
        cout<<pNum[i]<<" ";  //输出1 2 3
    }
        cout<<endl;  
        delete pNum[];
        pNum[]=nullptr;      //释放完后置空       
}

用字符串方式申请一串内存时做初始化

    //字符数组方式初始化
    char* str=new char[20]{'A','B','\0'};
    cout<<str<<endl;        //输出:AB
    delete[] str;
    str=nullptr;

    //直接用字符串的方式初始化
    str=new char[20]{"i love you"};  
    cout<<str<<endl;        //输出:i love you
    delete[] str;
    str=nullptr;

释放有且只有两种方式

  • delete 指针:单个变量内存释放
  • delete[ ] 指针:一段内存释放,[ ]中不用填释放长度 & 不存在[ ][ ]的情况 基本语法

结构体动态内存申请

结构体的内存申请不做初始化 

struct MM
{    
    int age;
    char* name;  //char name[20];
    void printstu()        
    { 
        cout<<name<<"\t"<<age<<endl;  
    }
};
void teststructMemory()
{
    //new一个对象
    int* p=new int;         //结构体动态内存申请和整型变量动态内存申请类似  
    MM* pMM=new MM;   
}

结构体申请内存时做初始化 

struct MM
{    
    int age;
    const char* name; //const char*类型的值不能用于初始化char*类型的实体 加const修饰
    void printMM()        
    { 
        cout << name << "\t" << age << endl; //打印字符串不需要加*,只需要首地址即可
    }
};
void teststructMemory()
{
    //new一个对象
    int* p = new int(23);          
    MM* pMM = new MM{"小明",18};   //报错:未写构造函数前 结构体只能用{ }初始化   
    pstu->printMM();               //调用成员函数打印一下 输出:小明  18
}

结构体申请内存时做初始化做修改时会出现问题(const导致不能修改数据)    

struct MM
{    
    int age;
    const char* name;
    void printMM()        //成员函数
    { 
        cout<<name<<"\t"<<age<<endl;  
    }
};
void teststructMemory()
{
    //new一个对象
    MM* pMM=new MM{"小明",18};    
    pMM->printMM();    
    pMM->name=new char[18];
    strcpy(pMM->name,"i love you");  //报错:可以给它拷贝了一段内存,但不能修改
}

结构体申请内存后做初始化

char* 类型的指针没有内存,不能拷贝东西进去(用strcpy_s 拷贝,name没有长度)strcpy_s中间的参数是用来描述name的长度的,要做二次申请,才能strcpy或者赋值

struct MM
{    
    int age;
    char* name;
    void printMM()        
    { 
        cout<<name<<"\t"<<age<<endl;  
    }
};
void teststructMemory()
{
    //new一个对象
    MM* pMM=new MM;          //先申请内存
    pMM->name=new char[20];  //二次申请 给name申请一段内存
    strcpy_s(pMM->name,20,"张三");
    pMM->age=19;
    pMM->printMM();
}

/*输出*/

张三 19

结构体的内存释放

申请和释放顺序相反,先申请,后释放

反过来会中断,出现内存的重复释放,pMM不存在,怎么释放pMM的name?

struct MM
{    
    int age;
    char* name;
    void printMM()        //成员函数
    { 
        cout<<name<<"\t"<<age<<endl;  
    }
};
void teststructMemory()
{
    //new一个对象
    MM* pMM=new MM;  
    pMM->name=new char[20];  //二次申请 给name申请一串内存
    strcpy_s(pMM->name,20,"张三");
    pMM->age=19;
    pMM->printMM();
    delete[]pMM->name;
    delete pMM;              //1个结构体变量的内存释放
}

结构体中char* 复制字符串为啥要用const?

跟赋值的值有关系,c++对const要求更严格,赋值语句两边类型必须一致 

void testConst()
{
    char* str = "ILoveYou";    //报错:指针变量指向常量地址,类型不一致 指针变量=常量地址
    char str2[] = "ILoveYou";  
    char* str3 = str2;         //不是常量区,是栈区变量,可以直接指向
}

拓展(c语言malloc( )、calloc( )、realloc( )申请内存)

 malloc( )

void print(int array[],int arrayNum)            //打印数组
{
    for(int i = 0;i < arrayNum; i++)
    {
        cout << array[i] << " ";
    }
        cout << endl;

}
void testMalloc()
{
    //等效于产生了一个数组int pMnum[3]
    int* pMnum = (int*)malloc(sizeof(int)*3);    //分配内存的大小
    if(pMNum == NULL)                            //申请内存可能失败
        return;
    memset(pMNum,0,sizeof(int)*3);               //内存初始化为0
    print(pNum,3);                               //申请内存不做初始化
}

 calloc( )

void testCalloc()
{
    int* pCNum=(int*)calloc(3,sizeof(int));   
   
}
/*输出 类似memset的作用*/

0 0 0

void*_cdecl calloc(size_t_Count,size_t_Size)     //变量个数|变量大小

 realloc( )- - -内存不够,重新申请,原来数据还在

void testRealloc()
{
    int* pInt=(int*)malloc(sizeof(int));
    if(pMNum==NULL)                         //申请内存可能失败
        return;    
    *pInt=1999;
    pInt=(int*)realloc(pInt,sizeof(int)*3); //原来只有一个变量的内存,现在有3个变量的内存
    pInt[1]=123;
    pInt[2]=134;
    print(pInt,3);
    free(pInt);
}
/*输出*/

1999 123 1234
  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

qiuqiuyaq

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值