程序在运行时,内存主要分为6个存储区:
栈区(Stack): 通常位于内存的高地址部分。
代码区(Text Segment):位于内存的低地址部分。
内存区域 | 功能 |
栈区(Stack) | 局部变量,函数参数等存储在该区,由编译器自动分配和释放。 |
堆区(Heap) | 程序员手动分配和释放(new,delete),属于动态分配方式。内存空间不连续,因此会产生内存碎片。 |
未初始化数据区(BBS) | 未初始化或初始化为0的全局变量和静态变量 (Block Started by Symbol) |
全局数据区(global Data Segment) | 程序初始化时的常量,全局变量,静态变量分配到该区,到程序结束时自动释放 |
文字常量区( text constant segment) | 字符串常量,在程序中用于显示文字,初始化编译时的一些内容;只读; |
程序代码区(Code Segment) | 存放程序的二进制代码,只读; |
堆和栈的区别:
分类 | 堆(heap) | 栈(stack) |
管理方式 | 程序员分配,容易产生memory leak | 系统自动分配和释放 |
空间结构 | 堆得内存空间是不连续的,由一个记录空间空间的链表负责管理, | 栈的内存空间是连续的,即栈顶地址和最大空间是确定的; |
空间大小 | 内存空间几乎没有限制,在32位系统下,内存空间大小可达到4G | 一般windows下是2M,linux下是8M |
生长方向 | 向着内存地址增大的方向生长的 | 向着内存地址减小的方向生长的 |
碎片问题 | 每次在空闲链表中遍历到第一个大于申请空间的节点, 每次分配的空间大小一般不会正好等于申请的内存大小, 频繁的new操作势必会产生大量的空间碎片 | 内存空间是连续的,先进后出的方式保证不会产生零碎的空间 |
分配效率 | 堆是c/c++函数库提供的, 当申请空间时需要按照一定的算法搜索足够大小的内存空间, 当没有足够的空间时,还需要额外的处理,因此效率较低。 | 机器系统提供的数据结构,计算机会在底层对栈提供支持, 出栈进栈由专门的指令执行,因此效率较高。 |
存储内容 | 在函数调用时,第一个进栈是主函数中后下一条指令(函数调用语句 下一条可执行语句)地址,然后是函数各个参数,在大多数C编译器中, 参数是由右往左入栈,然后是函数中局部变量。注意静态变量是不入栈。 当本次函数调用结束后,局部变量先出栈,然后是参数,最后栈顶指针指向最开始存地址,也就是主函数中下一条指令,程序由该点继续运行。 | 一般是在堆头部用一个字节存放堆大小。堆中具体内容有程序员安排。 |
memset函数
memset
函数用于将内存块填充为特定值。它是 C++ 标准库的一部分,继承自 C 标准库。memset
函数的原型如下:
void* memset(void* ptr, int value, size_t num);
ptr
是指向要填充的内存块的指针。value
是要设置的值。num
是要设置为该值的字节数。注意事项:memset
在字节级别上工作。
使用 memset
时要小心 size 参数。传递大于分配内存的大小可能导致内存损坏。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | /**************************************************************** * Description: memset function * Author: Alex Li * Date: 2023-11-20 11:03:40 * LastEditTime: 2023-11-20 11:03:43 ****************************************************************/ #include <iostream> using namespace std; int main() { char arr0[10]; int arr1[10]; int arr2[10]; memset(arr0, '-', sizeof(arr0)); memset(arr1, 0, sizeof(arr1)); memset(arr2, 1, sizeof(arr2)); for (int i=0;i<10;i++)cout<<arr0[i]<<' '; cout<<'\n'; for (int i =0; i <10; i++)cout<<arr1[i]<<' '; cout<<'\n'; for (int i =0; i <10; i++)cout<<arr2[i]<<' '; //这个输出16843009,是因为memset按字节填充,所以 //int类型,有4个字节,填充为00000001000000010000000100000001,等于16843009 return 0; } |