内存管理

程序在运行时,内存主要分为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;
}
Scroll to Top