
🫧个人主页:小年糕是糕手
💫个人专栏:《C++》《C++同步练习》《数据结构》《C语言》
🎨你不能左右天气,但你可以改变心情;你不能改变过去,但你可以决定未来!

目录
[二、C++中的new / delete](#二、C++中的new / delete)
一、内存划分
知识回顾:
- 本质:程序运行时操作系统分配的内存区域,按功能划分为不同段,管理数据的存储与生命周期。
- 核心目的:合理管理不同类型数据的存储(如临时变量、全局数据、动态内存),优化资源使用与访问效率。
- 基本划分(常见区域) :
- 栈区(Stack):存储局部变量、函数参数、返回地址;自动分配 / 释放,空间小、速度快。
- 堆区(Heap) :存储动态分配数据(如
new/malloc申请的内存);手动分配 / 释放,空间大、灵活但需自行管理。- 全局 / 静态区 :存储全局变量、静态变量(
static修饰);程序启动时分配,结束时释放。- 代码段:存储程序的二进制指令;只读、共享。
- 常量区:存储字符串常量等不可修改数据;只读。
- 核心特点 :
- 不同区域的生命周期不同(栈区随函数调用销毁,堆区手动控制,全局区随程序生命周期);
- 不同区域的访问权限不同(代码段 / 常量区只读,栈 / 堆 / 全局区可读可写)。
1、看下列代码,解决下列问题:
cppint 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"; 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); }答案、解析:
2、下面有关c++内存分配堆栈说法错误的是()A.对于栈来讲,是由编译器自动管理,无需我们手工控制;对于堆来说,释放工作由程序员控制
B. 对于栈来讲,生长方向是向下的,也就是向着内存地址减小的方向;对于堆来讲,它的生长方向是向上的,是向着内存地址增加的方向增长
C.对于堆来讲,频繁的 new / delete 势必会造成内存空间的不连续,从而造成大量的碎片,使程序效率降低。对于栈来讲,则不会存在这个问题
D.一般来讲在 32 位系统下,堆内存可以达到4G的空间,但是对于栈来讲,一般都是有一定的空间大小的
答案:D
解析:
A:栈区主要存在局部变量和函数参数,其空间的管理由编译器自动完成,无需手动控制,堆区是自己申请的空间,在不需要时需要手动释放
B:栈区先定义的变量放到栈底,地址高,后定义的变量放到栈顶,地址低,因此是向下生长的,堆区则相反
C:频繁的申请空间和释放空间,容易造成内存碎片,甚至内存泄漏,栈区由于是自动管理,不存在此问题
D:32位系统下,最大的访问内存空间为4G,所以不可能把所有的内存空间当做堆内存使用,故错误
3、C++中关于堆和栈的说法,哪个是错误的()A.堆的大小仅受操作系统的限制,栈的大小一般较小
B.在堆上频繁的调用new/delete容易产生内存碎片,栈没有这个问题
C.堆和栈都可以静态分配
D.堆和栈都可以动态分配
答案:C
解析:
A:堆大小受限于操作系统,而栈空间一般有系统直接分配
B:频繁的申请空间和释放空间,容易造成内存碎片,甚至内存泄漏,栈区由于是自动管理,不存在此问题
C:堆无法静态分配,只能动态分配
D:栈可以通过函数_alloca进行动态分配,不过注意,所分配空间不能通过free或delete进行释放
二、C++中的new / delete
知识回顾:
- 本质 :C++ 中用于动态内存管理 的运算符,对应 C 语言的
malloc/free,但会自动调用对象的构造 / 析构函数。- 核心目的:在堆区手动分配 / 释放内存,管理对象的动态生命周期(按需创建 / 销毁,灵活控制内存)。
- 基本用法 :
- new :
类型* 指针 = new 类型(初始化值);(分配单个对象);类型* 指针 = new 类型[数量];(分配对象数组);分配时自动调用构造函数。- delete :
delete 指针;(释放单个对象);delete[] 指针;(释放对象数组);释放时自动调用析构函数。- 规则 :
new与delete必须匹配使用 (单个对象对应delete,数组对应delete[],否则可能内存泄漏 / 未调用析构);- 若
new分配失败,会抛出bad_alloc异常(C++11 后可使用new(nothrow)返回空指针);- 对于含动态资源的对象(如成员是堆指针),需确保析构函数中释放资源,避免内存泄漏。
1、c++语言中,类ClassA的构造函数和析构函数的执行次数分别为()ClassA *pclassa=new ClassA[5];
delete pclassa;
A.5,1 B.1,1 C.5,5 D.程序可能崩溃
答案:D
解析:
A:申请对象数组,会调用构造函数5次,delete由于没有使用[ ],此时只会调用一次析构函数,但往往会引发程序崩溃
B:构造函数会调用5次
C:析构函数此时只会调用1次,要想完整释放数组空间,需要使用[ ]
D:正确
2、函数参数使用的空间是在()中申请的,malloc或new是在()中申请空间的?A.堆,栈 B.栈,堆 C.栈, 栈 D.堆,堆
答案:B
解析:
A:参数在栈空间存放,malloc或new申请的空间为堆区
B:正确
C:参数在栈空间存放,malloc或new申请的空间为堆区
D:参数在栈空间存放,malloc或new申请的空间为堆区
3、下面有关malloc和new,说法错误的是()A.new 是创建一个对象(先分配空间,再调构造函数初始化), malloc分配的是一块内存
B.new 初始化对象,调用对象的构造函数,对应的delete调用相应的析构函数,malloc仅仅分配内存,free仅仅回收内存
C.new和malloc都是保留字,不需要头文件支持
D.new和malloc都可用于申请动态内存,new是一个操作符,malloc是是一个函数
答案:C
解析:
A:new会申请空间,同时调用构造函数初始化对象,malloc只做一件事就是申请空间
B:new / delete与malloc / free最大区别就在于是否会调用构造函数与析构函数
C:需要头文件malloc.h,只是平时这个头文件已经被其他头文件所包含了,用的时候很少单独引入,故错误
D:new是操作符,malloc是函数
4、设已经有A,B,C,D4个类的定义,程序中A,B,C,D析构函数调用顺序为()C c;
void main()
{
A*pa=new A();
B b;
static D d;
delete pa;
}
答案:ABDC
解析:
首先手动释放pa, 所以会先调用A的析构函数,其次会跟定义相反的顺序释放局部对象,这里只有b,就释放b,再释放静态局部对象d,再释放全局对象c
5、使用 char* p = new char[100]申请一段内存,然后使用delete p释放,有什么问题()A.会有内存泄露
B.不会有内存泄露,但不建议用
C.编译就会报错,必须使用delete [ ]p
D.编译没问题,运行会直接崩溃
答案:B
解析:
A:对于内置类型,此时delete就相当于free,因此不会造成内存泄漏
B:正确
C:编译不会报错,建议针对数组释放使用delete[ ](如果是自定义类型,不使用方括号就会运行时错误)
D:对于内置类型,程序不会崩溃,但不建议这样使用
6、以下代码中,A 的构造函数和析构函数分别执行了几次:()A*pa=new A[10];
delete [ ]pa;
A.1、1 B.10、10 C.1、10 D.10、1
答案:B
解析:A:申请数组空间,构造函数调用的次数就是数组的大小
B:正确
C:申请数组空间,构造函数调用的次数就是数组的大小
D:如果释放数组空间,delete使用了[ ],则会对应的调用数组大小次数的析构函数



