C++ delete语句

简介: C++ delete语句

C++中的五种内存


在C++中内存分为五个区:堆、栈、自由存储区、全局/静态存储区和常量存储区。

堆区:用户使用new获得的内存在这里。用户需要自行管理其声明周期,也就是说一个new要对应一个delete,如果因为某些原因(之后我会说明一些可能的原因)内存没有被释放,那么在程序结束后,会由操作系统自行回收,这显然不是我们想看到的。

栈区:存储局部变量、函数参数等,比方说你在某个函数里定义了一个int变量a,这个a就存放在栈区。这块内存的生命周期由系统管理,不需要我们去操心。

自由存储区:用malloc分配的内存放置在这里。这块内存和堆很相似,不过是使用free来释放内存的。

全局/静态存储区:存放全局变量和静态变量。

常量存储区:存放常量,不允许更改。

new和delete


void testDelete(){
    int *p = new int;
    cout << *p << endl;
    cout << &p << endl;
    *p=1;
    cout << *p << endl;
    cout << &p << endl;
    delete p;
    cout << *p << endl;
    cout << &p << endl;
    p = nullptr; //程序到此停止执行
    cout << *p << endl;
    cout << &p << endl;
}

 

可以看出 delete指针并非将该指针弃置不用,而是将其指向的内存中的数据清除,但是指针仍然指向原来的内存!

如果我们想按照delete的英文本意,把这个指针从世界上彻底销毁,需要将指针的值赋为nullptr

智能指针

如果可以,我们应该使用STL提供的shared_ptr和unique_ptr替换原始指针,这样我们可以不用自行管理内存的生命周期,获得类似JAVA和C#的自动内存回收体验。

shared_ptr<int> p = make_shared<int>(1);

shared_ptr<int> q(new int(2));

注意:

不要使用相同的内置指针初始化(或reset)多个智能指针。

不delete get()返回的指针

不适用get()初始化或reset另一个智能指针

如果使用了get()返回的指针,记住当最后一个对应的智能指针销毁后,你的指针就变为无效了。

不过你使用智能指针管理的资源不是new分配的内存,记住传递给它一个删除器。

allocator类

该类帮助我们将内存分配和对象构造分离开来,它分配的内存是原始的、未构造的。

allocator<string> alloc;//可以分配string的allocator对象

auto const p = alloc.allocate(n);//分配n个未初始化的string

malloc/free

从C程序员转换过来的C++程序员总是有个困惑:new/delete到底究竟和C语言里面的malloc/free比起来有什么优势?或者是一样的?

malloc/free只是对内存进行分配和释放;new/delete还负责完成了创建和销毁对象的任务。

new的安全性要高一些,因为他返回的就是一个所创建的对象的指针,对于malloc来说返回的则是void*,还要进行强制类型转换,显然这是一个危险的漏洞。

我们可以对new/delete重载,使内存分配按照我们的意愿进行,这样更具有灵活性,malloc则不行。

不过,new/delete也并不是十分完美,大概最大的缺点就是效率低(针对的是缺省的分配器),原因不只是因为在自由存储区上分配(和栈上对比),而且new只是对于堆分配器(malloc/realloc/free)的一个浅层包装,没有针对小型的内存分配做优化。另外缺省分配器具有通用性,它管理的是一块内存池,这样的管理往往需要消耗一些额外空间。我们可以针对new/delete进行重写以追求更高的效率,对于这方面更深入的探讨可以参考《Effective C++》第八章。

static void* operator new(size_t sz);

   static void operator delete(void* p);

new 对象实际上做了2件事:调用opeator new,在自由存储区分配一个sizeof(A)大小的内存空间;然后调用构造函数A(),在这块内存空间上类砖砌瓦,建造起我们的对象。

同样对于delete,则做了相反的两件事:调用析构函数~A(),销毁对象,调用operator delete,释放内存。


目录
相关文章
|
4月前
|
存储 Java 编译器
C++:内存管理|new和delete
C++:内存管理|new和delete
|
4月前
|
存储 算法 编译器
【C++ 内存管理 重载new/delete 运算符 新特性】深入探索C++14 新的/删除的省略(new/delete elision)的原理与应用
【C++ 内存管理 重载new/delete 运算符 新特性】深入探索C++14 新的/删除的省略(new/delete elision)的原理与应用
137 0
|
4月前
|
编译器
【【C++11特性篇】【强制/禁止 】生成默认函数的关键字default&delete(代码演示)
【【C++11特性篇】【强制/禁止 】生成默认函数的关键字default&delete(代码演示)
|
24天前
|
C++
C++(十九)new/delete 重载
本文介绍了C++中`operator new/delete`重载的使用方法,并通过示例代码展示了如何自定义内存分配与释放的行为。重载`new`和`delete`可以实现内存的精细控制,而`new[]`和`delete[]`则用于处理数组的内存管理。不当使用可能导致内存泄漏或错误释放。
|
1月前
|
存储 程序员 编译器
c++学习笔记08 内存分区、new和delete的用法
C++内存管理的学习笔记08,介绍了内存分区的概念,包括代码区、全局区、堆区和栈区,以及如何在堆区使用`new`和`delete`进行内存分配和释放。
40 0
|
2月前
|
存储 C语言 C++
【C/C++】动态内存管理( C++:new,delete)
C++的`new`和`delete`用于动态内存管理,分配和释放内存。`new`分配内存并调用构造函数,`delete`释放内存并调用析构函数。`new[]`和`delete[]`分别用于数组分配和释放。不正确匹配可能导致内存泄漏。内置类型分配时不初始化,自定义类型则调用构造/析构。`operator new`和`operator delete`是系统底层的内存管理函数,封装了`malloc`和`free`。定位`new`允许在已分配内存上构造对象,常用于内存池。智能指针等现代C++特性能进一步帮助管理内存。
|
3月前
|
C++
C/C++内存管理(2):`new`和`delete`的实现原理
C/C++内存管理(2):`new`和`delete`的实现原理
|
3月前
|
安全 C++ 开发者
C++一分钟之-动态内存管理:new与delete
【6月更文挑战第19天】在C++中,`new`和`delete`用于动态内存管理,分配和释放堆内存。不正确使用可能导致内存泄漏和悬挂指针。要避免这些问题,确保每次`new`都有匹配的`delete`,释放内存后设指针为`nullptr`。使用`delete[]`释放数组,避免重复释放。智能指针如`std::unique_ptr`可自动管理内存,减少手动管理的风险。通过实例展示了如何使用智能指针进行安全的内存操作。
42 4
|
2月前
|
C++
C++基础知识(二:引用和new delete)
引用是C++中的一种复合类型,它是某个已存在变量的别名,也就是说引用不是独立的实体,它只是为已存在的变量取了一个新名字。一旦引用被初始化为某个变量,就不能改变引用到另一个变量。引用的主要用途包括函数参数传递、操作符重载等,它可以避免复制大对象的开销,并且使得代码更加直观易读。
|
4月前
|
存储 编译器 C++
【C++】内存管理和模板基础(new、delete、类及函数模板)
【C++】内存管理和模板基础(new、delete、类及函数模板)
46 1