C++初阶(九)内存管理(上)

简介: C++初阶(九)内存管理(下)

一、C/C++内存分布

我们先来看下面的一段代码和相关问题

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);
}

1、选择题

选项: A.栈 B.堆 C.数据段(静态区) D.代码段(常量区)

globalVar在哪里?____ staticGlobalVar在哪里?____

staticVar在哪里?____ localVar在哪里?____

num1 在哪里?____

C C C A A

char2在哪里?____ *char2在哪里?___

pChar3在哪里?____ *pChar3在哪里?____

ptr1在哪里?____ *ptr1在哪里?____

A A A C A B

2、填空题

sizeof(num1) = ____;

sizeof(char2) = ____; strlen(char2) = ____;

sizeof(pChar3) = ____; strlen(pChar3) = ____;

sizeof(ptr1) = ____;

40 5 4 4/8 4 4/8

3、sizeof 和 strlen 区别?

sizeof是运算符计算的是内存的大小,包括’\0’,strlen计算的是字符串的大小,不计算’\0’。

4、总结

  1. 栈区主要存在局部变量和函数参数,其空间的管理由编译器自动完成,无需手动控制,堆区是自己申请的空间,在不需 要时需要手动释放。
  2. 对于栈来讲,生长方向是向下的,也就是向着内存地址减小的方向;对于堆来讲,它的生长方向是向上的,是向着内存地址增加的方向增长。
  3. 对于堆来讲,频繁的 new/delete 势必会造成内存空间的不连续,从而造成大量的碎片,使程序效率降低。对于栈来讲,则不会存在这个问题。
  4. 32位系统下,最大的访问内存空间为4G,所以不可能把所有的内存空间当做堆内存使用。
  5. 栈可以静态分配,堆不可以。
  6. 栈和堆都可以动态分配。
  7. 内存映射段是高效的I/O映射方式,用于装载一个共享的动态内存库。用户可使用系统接口创建共享共享内存,做进程间通信。
  8. 数据段–存储全局数据和静态数据。
  9. 代码段–可执行的代码/只读常量。

二、 C语言中动态内存管理:malloc/calloc/realloc/free

void Test ()
{
int* p1 = (int*) malloc(sizeof(int));
free(p1);
// 1.malloc/calloc/realloc的区别是什么?
int* p2 = (int*)calloc(4, sizeof (int));
int* p3 = (int*)realloc(p2, sizeof(int)*10);
// 这里需要free(p2)吗?
free(p3 );
}

1、 malloc/calloc/realloc的区别?

相同点

1.都是从堆上申请空间;

2.都需要对返回值判空;

3.都需要用户free释放;

4.返回值类型相同(都是void*);

5.都需要类型转化;

6.底层实现是一样的,都需要开辟多余的空间,用来维护申请的空间。

不相同

1.函数名字不同,参数类型不同;

2.calloc函数会对申请空间初始化,并且初始化为0;

3.malloc函数申请空间必须使用memset进行初始化;

4.realloc函数是对已经存在的空间进行调整,当第一个参数传入NULL的时候和malloc函数一样,其调整分为两种请况:

A.调整的空间比原有空间大

a.大了一点:多出来的空间小于下面空闲的空间
      调整方法:
      (1)直接延伸申请空间;
      (2)返回空间首地址。
    b.打了很多:多出来空间大于下面空闲空间
    调整方法:
    (1)重新开辟新空间;
    (2)将旧空间的内容拷贝到新空间中;
    (3)释放旧空间;
    (4)返回新空间的首地址。

B.调整的空间比原有空间小

调整方法:
   (1)将原有空间缩小;
   (2)返回旧空间首地址。

2、 malloc的实现原理?

glibc中malloc实现原理


三、 C++内存管理方式

C语言内存管理方式在C++中可以继续使用,但有些地方就无能为力,而且使用起来比较麻烦,因此C++又提出了自己的内存管理方式:通过new和delete操作符进行动态内存管理。

1、 new/delete操作内置类型

1、演示1

2、演示2

3、演示3

注意:申请和释放单个元素的空间,使用new和delete操作符,申请和释放连续的空间,使用new[]和delete[],注意:匹配起来使用。

目录
相关文章
|
22天前
|
存储 缓存 C语言
【c++】动态内存管理
本文介绍了C++中动态内存管理的新方式——`new`和`delete`操作符,详细探讨了它们的使用方法及与C语言中`malloc`/`free`的区别。文章首先回顾了C语言中的动态内存管理,接着通过代码实例展示了`new`和`delete`的基本用法,包括对内置类型和自定义类型的动态内存分配与释放。此外,文章还深入解析了`operator new`和`operator delete`的底层实现,以及定位new表达式的应用,最后总结了`malloc`/`free`与`new`/`delete`的主要差异。
42 3
|
29天前
|
存储 编译器 Linux
【c++】类和对象(上)(类的定义格式、访问限定符、类域、类的实例化、对象的内存大小、this指针)
本文介绍了C++中的类和对象,包括类的概念、定义格式、访问限定符、类域、对象的创建及内存大小、以及this指针。通过示例代码详细解释了类的定义、成员函数和成员变量的作用,以及如何使用访问限定符控制成员的访问权限。此外,还讨论了对象的内存分配规则和this指针的使用场景,帮助读者深入理解面向对象编程的核心概念。
71 4
|
2月前
|
存储 程序员 编译器
简述 C、C++程序编译的内存分配情况
在C和C++程序编译过程中,内存被划分为几个区域进行分配:代码区存储常量和执行指令;全局/静态变量区存放全局变量及静态变量;栈区管理函数参数、局部变量等;堆区则用于动态分配内存,由程序员控制释放,共同支撑着程序运行时的数据存储与处理需求。
138 21
|
2月前
|
程序员 C++ 容器
在 C++中,realloc 函数返回 NULL 时,需要手动释放原来的内存吗?
在 C++ 中,当 realloc 函数返回 NULL 时,表示内存重新分配失败,但原内存块仍然有效,因此需要手动释放原来的内存,以避免内存泄漏。
|
2月前
|
存储 C语言 C++
【C++打怪之路Lv6】-- 内存管理
【C++打怪之路Lv6】-- 内存管理
44 0
【C++打怪之路Lv6】-- 内存管理
|
2月前
|
存储 C语言 C++
【C/C++内存管理】——我与C++的不解之缘(六)
【C/C++内存管理】——我与C++的不解之缘(六)
|
2月前
|
程序员 C语言 C++
C++入门5——C/C++动态内存管理(new与delete)
C++入门5——C/C++动态内存管理(new与delete)
72 1
|
2月前
|
C++
C/C++内存管理(下)
C/C++内存管理(下)
50 0
|
2月前
|
存储 Linux C语言
C/C++内存管理(上)
C/C++内存管理(上)
39 0
|
2月前
|
Linux C++
Linux c/c++文件虚拟内存映射
这篇文章介绍了在Linux环境下,如何使用虚拟内存映射技术来提高文件读写的速度,并通过C/C++代码示例展示了文件映射的整个流程。
55 0