C/C++内存管理--1

简介: C/C++内存管理--1

一,C/C++内存分布

内存区域的大概介绍:


       C/C++中,我们目前需要了解的内存区域是栈区、堆区、静态区、常量区。其中,栈区用于临时存储数据,如函数的栈帧,局部变量等。堆区一般用来存储动态开辟的空间,如malloc、calloc、realloc、new等开辟的空间。静态区原名是代码段,一般存储全局变量和静态数据,在整个程序都可以使用。常量区用来存储常量,如字面量等。这些东西之前有过说明,这里我们简单提一下即可。


65e1dd660fef4b268805f51f0df4c537.png


       以上东西全为基础,接下来我们来看看以下代码中的数据的存储空间。


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";
    const char* pChar3 = "abcd";
    int* ptr1 = (int*)malloc(sizeof(int) * 4);
    int* ptr2 = (int*)calloc(4, sizeof(int));
    int* ptr3 = (int*)realloc(ptr2, sizeof(int) * 4);
    free(ptr1);
    free(ptr3);
}
选项 : A.栈  B.堆  C.数据段(静态区)  D.代码段(常量区)
globalVar在   C      staticGlobalVar在  C
staticVar在    C       localVar在    A
num1 在     A
char2在      A          * char2在    A
pChar3在   A         * pChar3在   D
ptr1在   A               * ptr1在   B

分析:前5个好理解,要注意的是后面六个选项。char2在函数栈帧中创建了一个数组,其代表了首元素的地址,存储在栈区中,而*char2代表首元素,也存储在栈区中。pChar3要注意的是,这里的const修饰的是*pChar3,即 "abcd" 是一个字面量,存储在常量区中,而pChar3是一个指针,存储在栈区中。ptr1的类型是int* ,指向堆区中开辟动态空间的首地址,因此,ptr1存储在栈区中,*ptr1指向数据,存储在堆区中。



805745e0d2464eaf87a531d07e6d1611.png

二,C++动态开辟空间

1,new/delete操作内置类型

       我们都知道,C语言中有malloc、calloc、realloc、free语法进行动态空间的管理,而C++中通过new和delete操作符进行动态空间管理。其中new用来开辟空间,delete用来释放空间。其中,new可以对创建的空间进行初始化。


//动态开辟一个int型的空间
int* p1 = new int;//里面是随机值,不会初始化
int* p2 = new int(1);//动态开辟一个空间并初始化为1
//动态开辟多个int型的空间
int* p3 = new int[5]{ 1, 2 };//动态开辟5个空间并初始化为1 2 0 0 0 
int* p4 = new int[10];//里面是随机值,不会初始化
//删除开辟一个空间
delete p1;
delete p2;
//删除开辟多个空间
delete[] p3;
delete[] p4;

       注意:C++中delete在释放中不支持一次多次释放,如下:


//下面是错误的用法
delete p1,p2;
delete[] p3,p4;


       new操作符在没有指定初始化的时候系统不会自动初始化。


#include <iostream>
#include <string>
using namespace std;
int main()
{
    int n = 2;
    int* a = new int[n];
    a[0] = 0;
    a[1] = 1;
    a = new int[2 * n];//重新分配空间大小,里面全部是随机值
    return 0;
}

2,new和delete操作自定义类型

       这里要说明的是,操作自定义时,new/delete 和 malloc/free的最大区别是 new/delete对于【自定义类型】除了开空间还会调用构造函数和析构函数进行空间的初始化和释放。


class A
{
public:
    A(int a = 0)
        : _a(a)
    {
        cout << "A():" << this << endl;
    }
    ~A()
    {
        cout << "~A():" << this << endl;
    }
private:
    int _a;
};
int main()
{
    //通过调试可见,动态开辟空间初始化过程中调用了构造函数
    //只调用一次构造函数
    A* p1 = new A;
    A* p2 = new A(1);
    A aa1(1);
    A aa2(1);
    A aa3(1);
    //调用了三次构造函数
    A* p3 = new A[3]{ aa1, aa2, aa3 };
    A* p4 = new A[3]{A(2), A(2), A(2) };
    A* p5 = new A[3]{ 3, 3, 3 };
    //通过调试可见,动态空间释放过程中调用了析构函数
    //只调用一次析构函数
    delete p1;
    delete p2;
    //调用了三次析构函数
    delete[] p3;
    delete[] p4;
    delete[] p5;
    return 0;
}

总的来说:


       new的本质:开空间+调用构造函数初始化。


       delete的本质:调用析构函数释放空间。


       通过以上可总结出,在开辟和释放的过程中,new关键字开辟了多少个动态类型空间,将会调用多少次构造函数;delete关键字释放了多少个动态类型空间,将会调用多少次析构函数。其中new开辟的空间无论是否进行初始化,构造函数都会被调用。


C/C++内存管理--2https://developer.aliyun.com/article/1424646?spm=a2c6h.13148508.setting.20.214f4f0eqBSn46

目录
打赏
0
0
0
0
1
分享
相关文章
玩转C++内存管理:从新手到高手的必备指南
C++中的内存管理是编写高效、可靠程序的关键所在。C++不仅继承了C语言的内存管理方式,还增加了面向对象的内存分配机制,使得内存管理既有灵活性,也更加复杂。学习内存管理不仅有助于提升程序效率,还有助于理解计算机的工作原理和资源分配策略。
什么是内存泄漏?C++中如何检测和解决?
大家好,我是V哥。内存泄露是编程中的常见问题,可能导致程序崩溃。特别是在金三银四跳槽季,面试官常问此问题。本文将探讨内存泄露的定义、危害、检测方法及解决策略,帮助你掌握这一关键知识点。通过学习如何正确管理内存、使用智能指针和RAII原则,避免内存泄露,提升代码健壮性。同时,了解常见的内存泄露场景,如忘记释放内存、异常处理不当等,确保在面试中不被秒杀。最后,预祝大家新的一年工作顺利,涨薪多多!关注威哥爱编程,一起成为更好的程序员。
【硬核】C++11并发:内存模型和原子类型
本文从C++11并发编程中的关键概念——内存模型与原子类型入手,结合详尽的代码示例,抽丝剥茧地介绍了如何实现无锁化并发的性能优化。
【c++】动态内存管理
本文介绍了C++中动态内存管理的新方式——`new`和`delete`操作符,详细探讨了它们的使用方法及与C语言中`malloc`/`free`的区别。文章首先回顾了C语言中的动态内存管理,接着通过代码实例展示了`new`和`delete`的基本用法,包括对内置类型和自定义类型的动态内存分配与释放。此外,文章还深入解析了`operator new`和`operator delete`的底层实现,以及定位new表达式的应用,最后总结了`malloc`/`free`与`new`/`delete`的主要差异。
83 3
【c++】类和对象(上)(类的定义格式、访问限定符、类域、类的实例化、对象的内存大小、this指针)
本文介绍了C++中的类和对象,包括类的概念、定义格式、访问限定符、类域、对象的创建及内存大小、以及this指针。通过示例代码详细解释了类的定义、成员函数和成员变量的作用,以及如何使用访问限定符控制成员的访问权限。此外,还讨论了对象的内存分配规则和this指针的使用场景,帮助读者深入理解面向对象编程的核心概念。
253 4
在 C++中,realloc 函数返回 NULL 时,需要手动释放原来的内存吗?
在 C++ 中,当 realloc 函数返回 NULL 时,表示内存重新分配失败,但原内存块仍然有效,因此需要手动释放原来的内存,以避免内存泄漏。
|
4月前
|
【C++打怪之路Lv6】-- 内存管理
【C++打怪之路Lv6】-- 内存管理
69 0
【C++打怪之路Lv6】-- 内存管理
|
4月前
|
C++
C/C++内存管理(下)
C/C++内存管理(下)
59 0
|
4月前
|
C/C++内存管理(上)
C/C++内存管理(上)
59 0
|
4月前
|
Linux c/c++文件虚拟内存映射
这篇文章介绍了在Linux环境下,如何使用虚拟内存映射技术来提高文件读写的速度,并通过C/C++代码示例展示了文件映射的整个流程。
93 0
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等