【C++同步练习】内存管理

🫧个人主页:小年糕是糕手

💫个人专栏:《C++》《C++同步练习》《数据结构》《C语言》

🎨你不能左右天气,但你可以改变心情;你不能改变过去,但你可以决定未来!



目录

一、内存划分

[二、C++中的new / delete](#二、C++中的new / delete)


一、内存划分

知识回顾:

  1. 本质:程序运行时操作系统分配的内存区域,按功能划分为不同段,管理数据的存储与生命周期。
  2. 核心目的:合理管理不同类型数据的存储(如临时变量、全局数据、动态内存),优化资源使用与访问效率。
  3. 基本划分(常见区域)
    1. 栈区(Stack):存储局部变量、函数参数、返回地址;自动分配 / 释放,空间小、速度快。
    2. 堆区(Heap) :存储动态分配数据(如new/malloc申请的内存);手动分配 / 释放,空间大、灵活但需自行管理。
    3. 全局 / 静态区 :存储全局变量、静态变量(static修饰);程序启动时分配,结束时释放。
    4. 代码段:存储程序的二进制指令;只读、共享。
    5. 常量区:存储字符串常量等不可修改数据;只读。
  4. 核心特点
    1. 不同区域的生命周期不同(栈区随函数调用销毁,堆区手动控制,全局区随程序生命周期);
    2. 不同区域的访问权限不同(代码段 / 常量区只读,栈 / 堆 / 全局区可读可写)。
      1、看下列代码,解决下列问题:
cpp 复制代码
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";
	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

知识回顾:

  1. 本质 :C++ 中用于动态内存管理 的运算符,对应 C 语言的malloc/free,但会自动调用对象的构造 / 析构函数。
  2. 核心目的:在堆区手动分配 / 释放内存,管理对象的动态生命周期(按需创建 / 销毁,灵活控制内存)。
  3. 基本用法
    1. new类型* 指针 = new 类型(初始化值);(分配单个对象);类型* 指针 = new 类型[数量];(分配对象数组);分配时自动调用构造函数。
    2. deletedelete 指针;(释放单个对象);delete[] 指针;(释放对象数组);释放时自动调用析构函数。
  4. 规则
    1. newdelete必须匹配使用 (单个对象对应delete,数组对应delete[],否则可能内存泄漏 / 未调用析构);
    2. new分配失败,会抛出bad_alloc异常(C++11 后可使用new(nothrow)返回空指针);
    3. 对于含动态资源的对象(如成员是堆指针),需确保析构函数中释放资源,避免内存泄漏。
      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使用了[ ],则会对应的调用数组大小次数的析构函数


相关推荐
Dev7z2 小时前
基于MATLAB的5G通信信号频谱分析与信道性能仿真研究
开发语言·5g·matlab
蒙奇D索大2 小时前
【数据结构】考研408|从B树到B+树:多路平衡的优化形态与数据库索引基石
数据结构·笔记·b树·学习·考研
不会代码的小猴2 小时前
C++的第十五天笔记
数据结构·c++·笔记
愚润求学2 小时前
【C++11】并发库
c++
波波0072 小时前
使用.NET 四步玩转 AI 绘图|不用Python、不买显卡
开发语言·c#·.net
tbRNA2 小时前
C++基础知识点(六)类和对象
开发语言·c++
小此方2 小时前
Re:从零开始学C++(二)基础精讲·下篇:内联函数与空指针
开发语言·c++
心.c2 小时前
初步了解Next.js
开发语言·前端·javascript·js
桃花岛主702 小时前
go-micro,v5启动微服务的正确方法
开发语言·后端·golang