您现在的位置是:首页 > 技术文章网站首页技术文章

[C++]动态内存

  • WangYe
  • 2020-08-03 16:04:53
  • 635 次阅读
了解C++动态内存

C++程序中内存分为两部分:

    1. 栈:在函数内部声明的所有变量都将占用栈内存;

    2. 堆:程序中未使用的内存,在程序运行时可用于动态分配内存;


分配堆内的内存,返回所分配的空间地址new运算符,不需要动态分配的内存空间可以使用delete运算符删除之前new运算符分配的内存;

new和delete运算符

使用new运算符来为任意数据类型动态分配内存通用语法:

new data-type;

参数:
    data-type:包括数组在内的任意内置的数据类型,也可以是包括类或结构在内的自定义任何数据类型;

例如,我们可以定义一个指向 double 类型的指针,然后请求内存,该内存在执行时被分配。我们可以按照下面的语句使用 new 运算符来完成这点:

double* pvalue  = NULL; // 初始化为 null 的指针
pvalue  = new double;   // 为变量请求内存

如果自由存储区已被用完,可能无法成功分配内存。所以建议检查new运算符是否返回NULL指针,并采取以下适当操作:

double* pvalue = NULL;
if(!(pvalue = new double))
{
    cout << "Error:out of memory." << endl;
    exit(1);
}

malloc()函数在C语言中出现,在C++依然存在,但建议尽量不要使用malloc()函数。new与malloc()函数相比,其主要有点:new不只是分配内存,还创建对象;

当某个已分配内存的变量不再需要,可以使用delete操作符释放所占内存:

delete pvalue;    //释放 pvalue 所指向内存


实例演示new和delete运算符:

#include <iostream>
using namespace std;

int main()
{
    double* pvalue = NULL;    //初始化为 null 的指针
    pvalue = new double;    //为变量请求内存
    
    *pvalue = 29494.99;    //再分配的地址储存值
    cout << "Value of pvalue:" << *pvalue << endl;
    
    delete pvalue;    //释放内存
    
    return 0;
}

结果:

图片.png


数组的动态内存分配

假设外卖为一个字符数组20个字符串的分配内存,可以使用如下:

char* pvalue = NULL;    //初始化为 null 指针
pvalue = new char[20];    //为变量请求内存

删除刚刚创建的数组语句如下:

delete [] pvalue;    //删除 pvalue 所指向的数组


new操作符多维数组分配内存

一维数组:

//动态分配,数组长度为m
int *array = new int [m];

//释放内存
delete [] array;

二维数组:

int **array
//假定数组第一维长度为m,第二维长度为n
//动态分配空间
array = new int *[m];
for(int i = 0;i < m;i++)
{
    array[i] = new int [n];
}

//释放
for(int i = 0;i < m;i++)
{
    delete [] array[i];
}
delete [] array;

二维数组实例:

#include <iostream>
using namespace std;

int main()
{
    int **p;
    int i,j;    //p[4][8]
    //开始分配4行8列的二维数组
    p = new int *[4];
    for(i=0;i<4;i++)
    {
        p[i] = new int [8];
    }
    for(i=0;i<4;i++)
    {
        for(j=0;j<8;j++)
        {
            p[i][j] = j*i;
        }
    }
    //打印数据
    for(i=0;i<4;i++)
    {
        for(j=0;j<8;j++)
        {
            if(j==0)
            cout << endl;
            cout << p[i][j] << "\t";
        }
    }
    //开始释放申请的堆
    for(i=0;i<4;i++)
    {
        delete [] p[i];
    }
    delete [] p;
    return 0;
}


三维数组

int ***array;
//假定数组第一维为m,第二维为n,第三维为h
//动态分配空间
array = new int **[m];
for(int i=0;i<m;i++)
{
    array[i] = new int *[n];
    for(int j=0;j<n;j++)
    {
        array[i][j] = new int [h];
    }
}
//释放
for(int i=0;i<m;i++)
{
    for(int j=0;j<n;j++)
    {
        delete[] array[i][j];
    }
    delete[] array[i];
}
delete[] array;

三维数组实例:

#include <iostream>
using namespace std;

int main()
{
    int i,j,k;    //p[2][3][4]
    
    int ***p;
    p = new int **[2];
    for(i=0;i<2;i++)
    {
        p[i] = new int *[3];
        for(j=0;j<3;j++)
        {
            p[i][j] = new int[4];
        }
    }
    //输出 p[i][j][k] 三维数据
    for(i=0;i<2;i++)
    {
        for(j=0;j<3;j++)
        {
            for(k=0;k<4;k++)
            {
                p[i][j][k] = i+j+k;
                cout << p[i][j][k] << "";
            }
            cout << endl;
        }
        cout << endl;
    }
    //释放内存
    for(i=0;i<2;i++)
    {
        delete [] p[i];
    }
    delete [] p;
    return 0;
}


对象的动态内存分配

对象与简单数据类型没有什么不同,如下:

#include <iostream>
using namespace std;

class Box
{
    public:
    Box(){
        cout << "调用构造函数!" << endl;
    }
    ~Box(){
        cout << "调用析构函数!" << endl;
    }
};

int main()
{
    Box* myBoxArray = new Box[4];
    
    delete [] myBoxArray;    //删除数组
    
    return 0;
}

如果要为一个包含四个 Box 对象的数组分配内存,构造函数将被调用 4 次,同样地,当删除这些对象时,析构函数也将被调用相同的次数(4次)。

当上面的代码被编译和执行时,它会产生下列结果

调用构造函数!
调用构造函数!
调用构造函数!
调用构造函数!
调用析构函数!
调用析构函数!
调用析构函数!
调用析构函数!


上一篇:[STL]认识set

下一篇:[C++]多线程

文章评论 (0)



Top