C++ 中用于动态内存的 的 new 和 delete 运算符

2022-11-14 16:44:27 浏览数 (1)


theme: channing-cyan highlight: a11y-dark


「这是我参与11月更文挑战的第21天,活动详情查看:2021最后一次更文挑战」

C/C 中的动态内存分配是指由程序员手动进行内存分配。动态分配的内存在堆上分配,非静态和局部变量在堆栈上分配内存。

什么是应用程序?

  • 动态分配内存的一种用途是分配可变大小的内存,这对于编译器分配的内存是不可能的,除了可变长度数组。
  • 最重要的用途是提供给程序员的灵活性。我们可以在需要和不再需要时自由分配和释放内存。这种灵活性在很多情况下都有帮助。此类情况的示例是Linked List、Tree等。

它与分配给普通变量的内存有何不同? 对于“int a”、“char str[10]”等普通变量,内存会自动分配和释放。对于像“int *p = new int[10]”这样的动态分配内存,程序员有责任在不再需要时释放内存。如果程序员不释放内存,则会导致内存泄漏(直到程序终止内存才会释放)。  在 C 中如何分配/释放内存? C 使用malloc() 和 calloc()函数在运行时动态分配内存,并使用 free() 函数释放动态分配的内存。C 支持这些函数并且还有两个操作符newdelete以更好、更简单的方式执行分配和释放内存的任务。 这篇文章是关于 new 和 delete 操作符的。

new 运算符

new 运算符表示在 Free Store 上分配内存的请求。如果有足够的内存可用,new 操作符会初始化内存并将新分配和初始化的内存的地址返回给指针变量。   

  • 使用 new 运算符的语法:要分配任何数据类型的内存,语法为:
代码语言:javascript复制
pointer-variable = new data-type;
  • 这里,指针变量是数据类型类型的指针。数据类型可以是任何内置数据类型,包括数组或任何用户定义的数据类型,包括结构和类。  例子: 
代码语言:javascript复制
代码语言:javascript复制
// 用 NULL 初始化的指针然后为变量请求内存
int *p = NULL; 
p = 新整数;   

            或

// 结合指针的声明和它们的赋值
int *p = new int;
  • 初始化内存: 我们还可以使用 new 运算符为内置数据类型初始化内存。对于自定义数据类型,需要一个构造函数(以数据类型作为输入)来初始化值。这是两种数据类型初始化的示例:
代码语言:javascript复制
指针变量 =新数据类型(值);
示例: 
int *p = new int(25); 
float *q = new float(75.25);

// 自定义数据类型
struct cust 
{ 
    int p; 
    cust(int q) : p(q) {} 
}; 

cust* var1 = new cust;// 工作正常,不需要构造函数

        或

cust* var1 = new cust(); // 工作正常,不需要构造函数


cust* var = new cust(25) // 如果注释此行,请注意错误
  • 分配内存块:  new 运算符也用于分配数据类型的内存块(数组)。 
代码语言:javascript复制
代码语言:javascript复制
指针变量=新数据类型[大小];
  • 其中 size(a variable) 指定数组中元素的数量。 
代码语言:javascript复制
代码语言:javascript复制
示例:
        int *p = new int[10]
  • 为连续 10 个 int 类型的整数动态分配内存,并返回指向序列第一个元素的指针,该元素被分配给 p(a pointer)。p[0] 指的是第一个元素,p[1] 指的是第二个元素,依此类推。

普通数组声明与使用 new 声明普通数组和使用 new 分配内存块之间存在差异。最重要的区别是,普通数组由编译器释放(如果数组是本地的,则在函数返回或完成时释放)。然而,动态分配的数组总是保留在那里,直到它们被程序员释放或程序终止。 如果在运行时没有足够的内存可用怎么办? 如果堆中没有足够的内存可供分配,则新请求通过抛出类型为 std::bad_alloc 的异常指示失败,除非“nothrow”与 new 运算符一起使用,在这种情况下它返回一个 NULL 指针。因此,在使用 new 程序之前检查 new 产生的指针变量可能是个好主意。

代码语言:javascript复制
int *p = new(nothrow) int; 
if (!p) 
{ 
   cout << "内存分配失败n"; 
}

删除操作符

由于释放动态分配的内存是程序员的责任,因此 C 语言为程序员提供了删除运算符。  句法:   

代码语言:javascript复制
// 释放指针变量指向的内存
delete pointer-variable;  

这里,pointer-variable 是指向new创建的数据对象的指针。  例子:   

代码语言:javascript复制
  delete p;
  delete q;

要释放指针变量指向的动态分配数组,请使用以下形式的delete:   

代码语言:javascript复制
// 释放指针变量所指向的内存块
delete[] pointer-variable;  

示例:
   // 它将释放 p 指向的整个数组。
    delete[] p;
代码语言:javascript复制
#include <iostream>
using namespace std;

int main ()
{
    int* p = NULL;

    p = new(nothrow) int;
    if (!p)
        cout << "allocation of memory failedn";
    else
    {
        *p = 29;
        cout << "Value of p: " << *p << endl;
    }

    float *r = new float(75.25);

    cout << "Value of r: " << *r << endl;

    int n = 5;
    int *q = new(nothrow) int[n];

    if (!q)
        cout << "allocation of memory failedn";
    else
    {
        for (int i = 0; i < n; i  )
            q[i] = i 1;

        cout << "Value store in block of memory: ";
        for (int i = 0; i < n; i  )
            cout << q[i] << " ";
    }

    delete p;
    delete r;

    delete[] q;

    return 0;
}

输出: 

代码语言:javascript复制
Value of p: 29
Value of r: 75.25
Value store in block of memory: 1 2 3 4 5 

0 人点赞