网站 流量 不够用,wordpress单页面代码,wordpress 生成小程序,网站开发后端技术C是如何做内存管理的#xff08;有哪些内存区域#xff09;?
#xff08;1#xff09;堆#xff0c;使用malloc、free动态分配和释放空间#xff0c;能分配较大的内存#xff1b;
#xff08;2#xff09;栈#xff0c;为函数的局部变量分配内存#xff0c;能分配…C是如何做内存管理的有哪些内存区域?
1堆使用malloc、free动态分配和释放空间能分配较大的内存
2栈为函数的局部变量分配内存能分配较小的内存
3全局/静态存储区用于存储全局变量和静态变量
4常量存储区专门用来存放常量
5自由存储区通过new和delete分配和释放空间的内存具体实现可能是堆或者内存池。
补充堆是C和操作系统的术语自由存储区是C的术语指的是通过new和delete动态分配和释放对象的抽象概念基本上C也会用堆区实现自由存储但程序员可以通过重载操作符改用其他内存实现自由存储比如全局变量做的对象池。
堆和栈的内存有什么区别
1堆中的内存需要手动申请和手动释放栈中内存是由OS自动申请和自动释放
2堆能分配的内存较大4G(32位机器)栈能分配的内存较小1M
3在堆中分配和释放内存会产生内存碎片栈不会产生内存碎片
4堆的分配效率低栈的分配效率高
5堆地址从低向上栈由高向下。
C和C分别使用什么函数来做内存的分配和释放有什么区别能否混用
C使用malloc/freeC使用new/delete前者是C语言中的库函数后者是C语言的运算符对于自定义对象malloc/free只进行分配内存和释放内存无法调用其构造函数和析构函数只有new/delete能做到完成对象的空间分配和初始化以及对象的销毁和释放空间不能混用具体区别如下
1new分配内存空间无需指定分配内存大小malloc需要
2new返回类型指针类型安全malloc返回void*再强制转换成所需要的类型
3new是从自由存储区获得内存malloc从堆中获取内存
4对于类对象new会调用构造函数和析构函数malloc不会核心。
什么是内存对齐(字节对齐)为什么要做内存对齐如何对齐
1内存对齐的原因关键在于CPU存取数据的效率问题。为了提高效率计算机从内存中取数据是按照一个固定长度的。比如在32位机上CPU每次都是取32bit数据的也就是4字节若不进行对齐要取出两块地址中的数据进行掩码和移位等操作写入目标寄存器内存效率很低。内存对齐一方面可以节省内存一方面可以提升数据读取的速度
2内容内存对齐指的是C结构体中的数据成员其内存地址是否为其对齐字节大小的倍数。
3对齐原则1结构体变量的首地址能够被其最宽基本类型成员的对齐值所整除2结构体内每一个成员的相对于起始地址的偏移量能够被该变量的大小整除3结构体总体大小能够被最宽成员大小整除如果不满足这些条件编译器就会进行一个填充(padding)。
4如何对齐****声明数据结构时字节对齐的数据依次声明然后小成员组合在一起能省去一些浪费的空间不要把小成员参杂声明在字节对齐的数据之间。
#pragma pack 指令这是一个编译器指令用于控制结构体或联合体中成员的对齐。例如#pragma pack(push, 1) 可以设置对齐为1字节而 #pragma pack(pop) 则恢复到之前的对齐设置。
#pragma pack(push, 1)
struct MyStruct {char a; // 1 byteint b; // 4 bytes
};
#pragma pack(pop)C11 alignas 关键字C11 引入了 alignas 关键字允许程序员显式指定变量或类型的最小对齐要求。
struct alignas(16) MyStruct {char a;int b;
};这里MyStruct 的实例将保证16字节对齐。
malloc、calloc、realloc、alloca
malloc申请指定字节数的内存。申请到的内存中的初始值不确定。calloc为指定长度的对象分配能容纳其指定个数的内存。申请到的内存的每一位bit都初始化为 0。realloc更改以前分配的内存长度增加或减少。当增加长度时可能需将以前分配区的内容移到另一个足够大的区域而新增区域内的初始值则不确定。alloca在栈上申请内存。程序在出栈的时候会自动释放内存。但是需要注意的是alloca 不具可移植性, 而且在没有传统堆栈的机器上很难实现。alloca 不宜使用在必须广泛移植的程序中。C99 中支持变长数组 (VLA)可以用来替代 alloca。
在 C 中malloc、calloc、realloc 和 alloca 是动态内存分配函数主要用于在运行时分配和管理内存。下面对它们分别进行定义、主要用途和区别分析。 1. mallocMemory Allocation
定义
malloc 函数用于分配指定大小的内存块返回一个指向该内存块的指针初始值为未定义即未初始化。
用途
用于在堆中分配内存。适合需要明确大小但不需要初始化的内存场景。
示例代码
#include cstdlib
#include iostreamint main() {int* ptr (int*)malloc(5 * sizeof(int)); // 分配 5 个整型大小的内存块if (ptr nullptr) {std::cout Memory allocation failed\n;return 1;}for (int i 0; i 5; i) {ptr[i] i 1; // 手动初始化}for (int i 0; i 5; i) {std::cout ptr[i] ;}std::cout \n;free(ptr); // 释放内存return 0;
}输出
1 2 3 4 52. callocContiguous Allocation
定义
calloc 用于分配指定数量的内存块并将所有分配的内存初始化为零。
用途
适合需要分配连续的内存块且初始化为零的场景。提高内存分配后的安全性。
示例代码
#include cstdlib
#include iostreamint main() {int* ptr (int*)calloc(5, sizeof(int)); // 分配 5 个整型大小的内存块并初始化为 0if (ptr nullptr) {std::cout Memory allocation failed\n;return 1;}for (int i 0; i 5; i) {std::cout ptr[i] ; // 输出已初始化为 0 的值}std::cout \n;free(ptr); // 释放内存return 0;
}输出
0 0 0 0 03. reallocReallocation
定义
realloc 用于调整之前分配的内存大小。它可能会移动原内存块到新的位置返回新内存块的指针。
用途
动态调整已分配内存大小。避免重新分配和手动复制数据。
示例代码
#include cstdlib
#include iostreamint main() {int* ptr (int*)malloc(3 * sizeof(int));if (ptr nullptr) {std::cout Memory allocation failed\n;return 1;}for (int i 0; i 3; i) {ptr[i] i 1;}// 调整内存大小为 5ptr (int*)realloc(ptr, 5 * sizeof(int));if (ptr nullptr) {std::cout Memory reallocation failed\n;return 1;}for (int i 3; i 5; i) {ptr[i] i 1; // 初始化新分配的部分}for (int i 0; i 5; i) {std::cout ptr[i] ;}std::cout \n;free(ptr);return 0;
}输出
1 2 3 4 54. allocaAllocate on Stack
定义
alloca 用于在栈上分配内存分配的内存在函数返回后会自动释放。
用途
用于短期内存分配避免显式释放。適合临时数据的内存管理。
示例代码
#include cstdlib
#include iostreamint main() {int* ptr (int*)alloca(5 * sizeof(int)); // 分配 5 个整型大小的内存块在栈上for (int i 0; i 5; i) {ptr[i] i 1;}for (int i 0; i 5; i) {std::cout ptr[i] ;}std::cout \n;// 不需要调用 freereturn 0;
}输出
1 2 3 4 5区别分析
特性malloccallocreallocalloca分配位置堆堆堆栈是否初始化否是初始化为 0保持原始数据扩展部分未初始化否与 malloc 类似内存调整不支持不支持支持不支持释放方式手动调用 free手动调用 free手动调用 free自动释放
malloc、free
用于分配、释放内存
malloc、free 使用
申请内存确认是否申请成功
char *str (char*) malloc(100);
assert(str ! nullptr);释放内存后指针置空
free(p);
p nullptr;new、delete
new / new[]完成两件事先底层调用 malloc 分配了内存然后调用构造函数创建对象。delete/delete[]也完成两件事先调用析构函数清理资源然后底层调用 free 释放空间。new 在申请内存时会自动计算所需字节数而 malloc 则需我们自己输入申请内存空间的字节数。
new、delete 使用
申请内存确认是否申请成功
int main()
{T* t new T(); // 先内存分配 再构造函数delete t; // 先析构函数再内存释放return 0;
}