searchusermenu
  • 发布文章
  • 消息中心
点赞
收藏
评论
分享
原创

c++内存分配说明及mysql常见内存分配操作

2023-12-07 02:05:03
15
0

c++内存分配说明及mysql常见内存分配操作

1 内存分配相关知识点

1.1 基本内存知识

什么是内存 一个C/C++编译的程序占用内存分为以下几个部分:

栈区(stack):由 编译器自动分配和释放, 存放的是 运行时函数分配的局部变量,函数参数,返回数据,返回地址等参数,其操作类似于数据结构中的

 

堆区(heap):由 由程序员手动分配, 一般存放的是 保存动态分配的变量和对象。堆区上的内存分配和释放是由程序员显式控制的。如果程序员没有释放,程序结束时可能由os回收,其分配类似于链表

 

全局区(静态区static)存放全局变量,静态数据,常量。程序结束后由系统释放,全局区分为已初始化全局区(data)和未初始化全局区(bss)。

 

常量区(文字常量区):存放的是 常量字符串。程序结束后由系统释放

 

代码区:存放的是 函数体(类成员函数和全局区)的二进制代码。程序结束后由系统释放

 

 

🌏 三种内存分配方式:

一.从静态存储区分配内存 从静态存储区分配的内存在 程序编译的时候就已经被分配完毕了,这块内存在程序的整个运行期间都会存在(例如全局变量,static变量)。

二.在栈上创建内存空间 在执行函数时, 函数内局部变量的存储单元可以在栈上创建,函数执行结束的时候,这些内存单元会自动被释放,栈内存分配运算内置于处理器的指令集,效率高,但是 分配的内存容量有限

三.在堆上分配内存(动态内存分配)🌟🌟🌟 在堆上分配内存亦被称为动态分配内存,程序在运行的时候使用malloc或者new申请 任意大小的内存,程序员自己负责在何时使用free和delete进行动态分配的内存的释放。 动态内存的生命周期是由程序员决定的,而且动态内存的申请和释放的使用过程非常灵活,but!如果在堆上分配了空间,则必须对堆上分配的内存进行回收,因为系统是无权对堆上的内存进行管理的,若只是申请了动态内存却不对内存进行释放,程序将会出现内存泄漏(OOM),且 频繁的分配和释放不同大小的堆空间将产生内存碎片

 

内存分配的简易示意图:

 

静态全局数据区:存放全局数据和静态数据 代码段:存放可执行代码只读常量 堆区:存放动态开辟的变量 栈区:非静态局部变量、函数参数,返回值等:存放全局数据和静态数据

在内存的角度来讲,堆和栈的区别:

管理方式不同:栈由编译器自动申请和释放空间,堆需要程序员手动申请和释放空间。

空间大小不同:栈的空间有限,32位平台下,VC6下默认为1M,而堆最大可以达到4G。

能否产生碎片: 栈和数据结构中的栈原理相同,在弹出一个元素之前,上一个元素已经弹出了,所以不会产生碎片,但如果不停的进行动态内存的申请和释放则会积累很多内存碎片。

生长方向的不同:堆的生长方向是向上的,也就是向着内存地址增加的方向,而栈刚好是相反的,栈是向着内存减小的方向生长的(因为栈的空间十分有限,所以栈是从上限往栈的下限生长的)

分配的方式不同:堆都是动态分配的,没有静态能进行分配的堆。而栈有静态分配和动态分配两种分配方式。静态分配是编译器完成的,比如局部变量的分配,动态分配在C++中由new函数进行分配。请注意:栈的动态分配和堆的是不同的,栈的动态分配由编译器进行释放,无需使用delete进行释放。

分配的效率不同:栈的效率比堆要高很多,因为栈是机器系统提供的数据结构,计算机在底层提供了栈的支持,分配专门的寄存器来存放栈的地址,压栈和出栈都有相应的指令,因此栈在分配的效率上是一定比堆上快的。而堆是由库函数提供的,机制很复杂,库函数会按照一定的算法进行搜索内存,因此比较慢

栈中内存的申请和释放: 通常来说,一个线程上的栈内存是有限的,通常为8MB左右(大小取决于运行环境),栈上的内存通常是由编译器自动管理的。当在栈上分配一个新的变量时,或进入一个函数时,栈的指针会向下移动(下压栈),相当于在栈上分配了一块内存。我们把变量分配在栈上,也就是利用了栈上的内存空间,当这个变量的生命周期结束的时候,栈的指针会上移,相当于回收了此块内存。

正是由于栈上的内存和分配和回收均是由编译器自动完成控制的,所以在上是不会发生内存泄漏的,只会发生栈 溢 出的情况(Stack Overflow),也就是分配的空间超过了规定的栈大小。

堆中内存的申请和释放: 堆中的内存是由程序直接控制的,程序可以通过[new/delete]来分配和回收内存,如果程序中通过[new]手动分配了一块内存,但忘记使用[delete]来回收内存,便会发生内存泄漏

 

静态全局变量(static),全局变量,静态局部变量(static),局部变量的区别:

静态全局变量和全局变量的区别: 1.静态全局变量和全局变量 都属于常量区 2.静态全局区 只在本文件中有效,别的文件如果向调用该变量,是调用不了的,且全局变量在别的文件中还可以调用。 3.如果别的文件中定义了一个该全局变量相同的的变量名,是会出错的。

静态局部变量和局部变量的区别: 1.静态局部变量是属于常量区的,而函数内部的局部变量属于栈区。 2.静态局部变量在该函数调用结束的时候,不会销毁,而是随着整个程序的结束而结束,静态局部变量不能被此函数外的函数调用。局部变量也是随着该函数的结束而结束的。 3.如果定义这两个变量的时候没有赋初始值,那么静态局部变量会自动的定义为0,而局部变量就是一个随机的值(一般的编译器会强制要求局部变量必须进行赋初值 而静态局部变量是否赋初值则不做强制性要求)。 4.静态局部变量在编译期间只赋值一次,以后每次调用函数时,不再赋值,而是直接调用上次的函数调用结束时的值。而局部变量在调用期间,每调用一次,便会对这个局部变量进行重新赋值

 

也就是说局部变量没有记忆性,每次到函数中,他都从最开始的状态执行,但是静态局部变量有记忆性,每次到函数中,它记得住上一次结束是它的值,这一次运行从上一次结束的状态执行。

总结:🎯 全局变量:可以被本程序所有对象或函数引用. 静态全局变量:是在全局变量声明前加上一个static关键字,使该变量只能在这个源文件可用. 局部变量:只能被函数内部引用,而无法被其他的对象或函数引用. 静态局部变量:通常放在函数内部,只能在函数内部被调用,只进行一次初始化,每次执行函数时保持上一次执行的值.

 

1.2 C/C++内存分配常见操作

1.2.1 sizeof

在C与C++中,内存的分配是以字节为单位进行分配的。sizeof也是统计的字节数。

例如:

🐵array_elements宏定义(mysql5.7源码)

#define array_elements(A) ((uint) (sizeof(A)/sizeof(A[0])))

就是用整个A数组的字节数/A[0]的字节数,那么结果就是整个数组的元素个数。

 

1.2.2 mysql_memory_register宏

#define mysql_memory_register(P1, P2, P3) \
inline_mysql_memory_register(P1, P2, P3)

mysql_memory_register内联了inline_mysql_memory_register函数,它的作用是注册 MySQL 5.7 版本中的内存信息,注册内存信息是为了实现内存管理和性能分析。在一个大型的软件系统中,准确地了解内存的分配和释放情况对于性能优化、内存泄漏检测和资源管理都非常重要。通过注册内存信息,可以跟踪和监控内存的使用情况,从而更好地管理系统的资源。

这个宏有三个参数

  • category(p1):表示内存分配的类别,可以用于对不同类型的内存分配进行分类。当编译时启用了 HAVE_PSI_MEMORY_INTERFACE 宏时,这个参数会被使用。

  • info(p2):表示一个指向 PSI_memory_info 结构的指针,用于存储内存信息。当编译时启用了 HAVE_PSI_MEMORY_INTERFACE 宏时,这个参数会被使用。

  • count(p3):表示要注册的内存块数量。

😄这里可以学到一个方法,如果一个函数想只让它在这个文件中生效,如何做?用statci关键字。但是如果其他外部文件要用怎么办?用inline关键字 + 一个宏内联到它

 

例如:

mysql_memory_register(AUDIT_LOG_PSI_CATEGORY, all_audit_log_memory, count);

分配了 count 个内存块,存储的信息放到 all_audit_log_memory 中,内存分配的类别是 AUDIT_LOG_PSI_CATEGORY。

mysql_memory_register 宏和 my_malloc 函数区别

  1. mysql_memory_register 宏:

    • 这是 MySQL 中的一个宏,用于将内存分配注册到内存统计和分析接口(PSI,Performance Schema Instrumentation)中,以便在性能分析和监控中能够追踪内存的使用情况。

    • 它通常在 MySQL 代码中用于分配一些特定的内存资源,比如分配内存池、内存缓冲区等等。

    • 通过注册到 PSI 接口,可以跟踪内存的分配和释放,以便进行性能分析和优化。

  2. my_malloc 函数:

    • my_malloc 是 MySQL 中的一个函数,用于分配内存块。

    • 它是直接的内存分配函数,用于分配一块指定大小的内存,并返回内存块的指针。

    • malloc 函数类似,my_malloc 用于一般的内存分配需求。

总之,mysql_memory_register 宏主要用于将内存分配注册到性能统计接口中,以进行性能监控和分析,而 my_malloc 函数是用于一般的内存分配操作。它们可以在不同的场景和需求下使用。

 

1.2.3 my_hash_init宏

my_hash_init 宏来初始化一个哈希表(hash table)

例如

my_hash_init(&exclude_commands, &my_charset_bin,
20, 0, 0,
(my_hash_get_key) command_get_key,
my_free, HASH_UNIQUE, key_memory_audit_log_commands);
  1. &exclude_commands:这是一个指向 my_hash_t 结构的指针,表示要初始化的哈希表对象。

  2. &my_charset_bin:这是一个指向字符集(character set)的指针,用于指定在哈希表中存储的字符数据的字符集。

  3. 20:这是哈希表的初始桶数(bucket count),即哈希表内部存储数据的存储桶数量。这个值通常会影响哈希表的性能和内存占用,较大的值可能会降低哈希冲突。

  4. 0:这是一个保留参数,通常用于将来的扩展或其他用途。在您提供的代码中,没有使用这个参数。

  5. 0:这是一个保留参数,通常用于将来的扩展或其他用途。在您提供的代码中,没有使用这个参数。

  6. (my_hash_get_key) command_get_key:这是一个函数指针,指向一个函数,用于计算存储在哈希表中的键(key)的哈希值。在您提供的代码中,command_get_key 函数用于计算哈希键的哈希值。

  7. my_free:这是一个用于释放内存的函数指针,用于在哈希表删除数据时释放相应的内存资源。

  8. HASH_UNIQUE:这是一个标志,用于指定哈希表中的键是否应该是唯一的。HASH_UNIQUE 表示键是唯一的,重复的键将不会被插入到哈希表中。

  9. key_memory_audit_log_commands:这是一个字符串,表示用于哈希键的内存池标识符,用于在哈希表中分配键的内存。

这里也可以学到一个方法一般哈希表的键值,可以就存它的name,value值存它的长度,这样,length(只保存数据用)可以一样,但是name是不一样的。

 

1.2.4 栈帧

栈帧(Stack Frame)是用于支持函数调用和返回的一种数据结构。每次调用函数时,系统会为该函数分配一个栈帧,栈帧中存储了函数的局部变量、参数、返回地址以及其他与函数调用相关的信息。当函数执行完毕后,栈帧会被释放,以便返回到调用函数的上下文。

栈帧通常包括以下几个重要的部分:

  1. 局部变量区域(Local Variables Area):用于存储函数中定义的局部变量。局部变量只在函数内部可见,函数调用结束后会自动销毁。

  2. 参数区域(Arguments Area):用于存储函数调用时传递的参数。这些参数可以是函数的输入,供函数在执行时使用。

  3. 返回地址(Return Address):用于存储函数执行完毕后要返回的位置。当函数执行完毕时,程序会从返回地址处继续执行。

  4. 调用者的帧指针(Caller's Frame Pointer):指向调用函数的栈帧。它可以用来访问调用函数的局部变量和参数。

  5. 其他上下文信息:可能包括存储寄存器的值、状态信息等。

栈帧的创建和销毁是通过栈(Stack)数据结构来管理的。栈是一种后进先出(Last-In-First-Out,LIFO)的数据结构,适用于函数调用和返回的特性。当函数被调用时,系统将新的栈帧压入栈顶,当函数返回时,对应的栈帧会被弹出。

栈帧的概念在程序执行和调试过程中起着重要的作用,它使得函数的嵌套调用能够正确地保存和恢复上下文信息,保证程序的正确执行和控制流的正确性。

 

 
0条评论
0 / 1000
张凡
7文章数
0粉丝数
张凡
7 文章 | 0 粉丝
原创

c++内存分配说明及mysql常见内存分配操作

2023-12-07 02:05:03
15
0

c++内存分配说明及mysql常见内存分配操作

1 内存分配相关知识点

1.1 基本内存知识

什么是内存 一个C/C++编译的程序占用内存分为以下几个部分:

栈区(stack):由 编译器自动分配和释放, 存放的是 运行时函数分配的局部变量,函数参数,返回数据,返回地址等参数,其操作类似于数据结构中的

 

堆区(heap):由 由程序员手动分配, 一般存放的是 保存动态分配的变量和对象。堆区上的内存分配和释放是由程序员显式控制的。如果程序员没有释放,程序结束时可能由os回收,其分配类似于链表

 

全局区(静态区static)存放全局变量,静态数据,常量。程序结束后由系统释放,全局区分为已初始化全局区(data)和未初始化全局区(bss)。

 

常量区(文字常量区):存放的是 常量字符串。程序结束后由系统释放

 

代码区:存放的是 函数体(类成员函数和全局区)的二进制代码。程序结束后由系统释放

 

 

🌏 三种内存分配方式:

一.从静态存储区分配内存 从静态存储区分配的内存在 程序编译的时候就已经被分配完毕了,这块内存在程序的整个运行期间都会存在(例如全局变量,static变量)。

二.在栈上创建内存空间 在执行函数时, 函数内局部变量的存储单元可以在栈上创建,函数执行结束的时候,这些内存单元会自动被释放,栈内存分配运算内置于处理器的指令集,效率高,但是 分配的内存容量有限

三.在堆上分配内存(动态内存分配)🌟🌟🌟 在堆上分配内存亦被称为动态分配内存,程序在运行的时候使用malloc或者new申请 任意大小的内存,程序员自己负责在何时使用free和delete进行动态分配的内存的释放。 动态内存的生命周期是由程序员决定的,而且动态内存的申请和释放的使用过程非常灵活,but!如果在堆上分配了空间,则必须对堆上分配的内存进行回收,因为系统是无权对堆上的内存进行管理的,若只是申请了动态内存却不对内存进行释放,程序将会出现内存泄漏(OOM),且 频繁的分配和释放不同大小的堆空间将产生内存碎片

 

内存分配的简易示意图:

 

静态全局数据区:存放全局数据和静态数据 代码段:存放可执行代码只读常量 堆区:存放动态开辟的变量 栈区:非静态局部变量、函数参数,返回值等:存放全局数据和静态数据

在内存的角度来讲,堆和栈的区别:

管理方式不同:栈由编译器自动申请和释放空间,堆需要程序员手动申请和释放空间。

空间大小不同:栈的空间有限,32位平台下,VC6下默认为1M,而堆最大可以达到4G。

能否产生碎片: 栈和数据结构中的栈原理相同,在弹出一个元素之前,上一个元素已经弹出了,所以不会产生碎片,但如果不停的进行动态内存的申请和释放则会积累很多内存碎片。

生长方向的不同:堆的生长方向是向上的,也就是向着内存地址增加的方向,而栈刚好是相反的,栈是向着内存减小的方向生长的(因为栈的空间十分有限,所以栈是从上限往栈的下限生长的)

分配的方式不同:堆都是动态分配的,没有静态能进行分配的堆。而栈有静态分配和动态分配两种分配方式。静态分配是编译器完成的,比如局部变量的分配,动态分配在C++中由new函数进行分配。请注意:栈的动态分配和堆的是不同的,栈的动态分配由编译器进行释放,无需使用delete进行释放。

分配的效率不同:栈的效率比堆要高很多,因为栈是机器系统提供的数据结构,计算机在底层提供了栈的支持,分配专门的寄存器来存放栈的地址,压栈和出栈都有相应的指令,因此栈在分配的效率上是一定比堆上快的。而堆是由库函数提供的,机制很复杂,库函数会按照一定的算法进行搜索内存,因此比较慢

栈中内存的申请和释放: 通常来说,一个线程上的栈内存是有限的,通常为8MB左右(大小取决于运行环境),栈上的内存通常是由编译器自动管理的。当在栈上分配一个新的变量时,或进入一个函数时,栈的指针会向下移动(下压栈),相当于在栈上分配了一块内存。我们把变量分配在栈上,也就是利用了栈上的内存空间,当这个变量的生命周期结束的时候,栈的指针会上移,相当于回收了此块内存。

正是由于栈上的内存和分配和回收均是由编译器自动完成控制的,所以在上是不会发生内存泄漏的,只会发生栈 溢 出的情况(Stack Overflow),也就是分配的空间超过了规定的栈大小。

堆中内存的申请和释放: 堆中的内存是由程序直接控制的,程序可以通过[new/delete]来分配和回收内存,如果程序中通过[new]手动分配了一块内存,但忘记使用[delete]来回收内存,便会发生内存泄漏

 

静态全局变量(static),全局变量,静态局部变量(static),局部变量的区别:

静态全局变量和全局变量的区别: 1.静态全局变量和全局变量 都属于常量区 2.静态全局区 只在本文件中有效,别的文件如果向调用该变量,是调用不了的,且全局变量在别的文件中还可以调用。 3.如果别的文件中定义了一个该全局变量相同的的变量名,是会出错的。

静态局部变量和局部变量的区别: 1.静态局部变量是属于常量区的,而函数内部的局部变量属于栈区。 2.静态局部变量在该函数调用结束的时候,不会销毁,而是随着整个程序的结束而结束,静态局部变量不能被此函数外的函数调用。局部变量也是随着该函数的结束而结束的。 3.如果定义这两个变量的时候没有赋初始值,那么静态局部变量会自动的定义为0,而局部变量就是一个随机的值(一般的编译器会强制要求局部变量必须进行赋初值 而静态局部变量是否赋初值则不做强制性要求)。 4.静态局部变量在编译期间只赋值一次,以后每次调用函数时,不再赋值,而是直接调用上次的函数调用结束时的值。而局部变量在调用期间,每调用一次,便会对这个局部变量进行重新赋值

 

也就是说局部变量没有记忆性,每次到函数中,他都从最开始的状态执行,但是静态局部变量有记忆性,每次到函数中,它记得住上一次结束是它的值,这一次运行从上一次结束的状态执行。

总结:🎯 全局变量:可以被本程序所有对象或函数引用. 静态全局变量:是在全局变量声明前加上一个static关键字,使该变量只能在这个源文件可用. 局部变量:只能被函数内部引用,而无法被其他的对象或函数引用. 静态局部变量:通常放在函数内部,只能在函数内部被调用,只进行一次初始化,每次执行函数时保持上一次执行的值.

 

1.2 C/C++内存分配常见操作

1.2.1 sizeof

在C与C++中,内存的分配是以字节为单位进行分配的。sizeof也是统计的字节数。

例如:

🐵array_elements宏定义(mysql5.7源码)

#define array_elements(A) ((uint) (sizeof(A)/sizeof(A[0])))

就是用整个A数组的字节数/A[0]的字节数,那么结果就是整个数组的元素个数。

 

1.2.2 mysql_memory_register宏

#define mysql_memory_register(P1, P2, P3) \
inline_mysql_memory_register(P1, P2, P3)

mysql_memory_register内联了inline_mysql_memory_register函数,它的作用是注册 MySQL 5.7 版本中的内存信息,注册内存信息是为了实现内存管理和性能分析。在一个大型的软件系统中,准确地了解内存的分配和释放情况对于性能优化、内存泄漏检测和资源管理都非常重要。通过注册内存信息,可以跟踪和监控内存的使用情况,从而更好地管理系统的资源。

这个宏有三个参数

  • category(p1):表示内存分配的类别,可以用于对不同类型的内存分配进行分类。当编译时启用了 HAVE_PSI_MEMORY_INTERFACE 宏时,这个参数会被使用。

  • info(p2):表示一个指向 PSI_memory_info 结构的指针,用于存储内存信息。当编译时启用了 HAVE_PSI_MEMORY_INTERFACE 宏时,这个参数会被使用。

  • count(p3):表示要注册的内存块数量。

😄这里可以学到一个方法,如果一个函数想只让它在这个文件中生效,如何做?用statci关键字。但是如果其他外部文件要用怎么办?用inline关键字 + 一个宏内联到它

 

例如:

mysql_memory_register(AUDIT_LOG_PSI_CATEGORY, all_audit_log_memory, count);

分配了 count 个内存块,存储的信息放到 all_audit_log_memory 中,内存分配的类别是 AUDIT_LOG_PSI_CATEGORY。

mysql_memory_register 宏和 my_malloc 函数区别

  1. mysql_memory_register 宏:

    • 这是 MySQL 中的一个宏,用于将内存分配注册到内存统计和分析接口(PSI,Performance Schema Instrumentation)中,以便在性能分析和监控中能够追踪内存的使用情况。

    • 它通常在 MySQL 代码中用于分配一些特定的内存资源,比如分配内存池、内存缓冲区等等。

    • 通过注册到 PSI 接口,可以跟踪内存的分配和释放,以便进行性能分析和优化。

  2. my_malloc 函数:

    • my_malloc 是 MySQL 中的一个函数,用于分配内存块。

    • 它是直接的内存分配函数,用于分配一块指定大小的内存,并返回内存块的指针。

    • malloc 函数类似,my_malloc 用于一般的内存分配需求。

总之,mysql_memory_register 宏主要用于将内存分配注册到性能统计接口中,以进行性能监控和分析,而 my_malloc 函数是用于一般的内存分配操作。它们可以在不同的场景和需求下使用。

 

1.2.3 my_hash_init宏

my_hash_init 宏来初始化一个哈希表(hash table)

例如

my_hash_init(&exclude_commands, &my_charset_bin,
20, 0, 0,
(my_hash_get_key) command_get_key,
my_free, HASH_UNIQUE, key_memory_audit_log_commands);
  1. &exclude_commands:这是一个指向 my_hash_t 结构的指针,表示要初始化的哈希表对象。

  2. &my_charset_bin:这是一个指向字符集(character set)的指针,用于指定在哈希表中存储的字符数据的字符集。

  3. 20:这是哈希表的初始桶数(bucket count),即哈希表内部存储数据的存储桶数量。这个值通常会影响哈希表的性能和内存占用,较大的值可能会降低哈希冲突。

  4. 0:这是一个保留参数,通常用于将来的扩展或其他用途。在您提供的代码中,没有使用这个参数。

  5. 0:这是一个保留参数,通常用于将来的扩展或其他用途。在您提供的代码中,没有使用这个参数。

  6. (my_hash_get_key) command_get_key:这是一个函数指针,指向一个函数,用于计算存储在哈希表中的键(key)的哈希值。在您提供的代码中,command_get_key 函数用于计算哈希键的哈希值。

  7. my_free:这是一个用于释放内存的函数指针,用于在哈希表删除数据时释放相应的内存资源。

  8. HASH_UNIQUE:这是一个标志,用于指定哈希表中的键是否应该是唯一的。HASH_UNIQUE 表示键是唯一的,重复的键将不会被插入到哈希表中。

  9. key_memory_audit_log_commands:这是一个字符串,表示用于哈希键的内存池标识符,用于在哈希表中分配键的内存。

这里也可以学到一个方法一般哈希表的键值,可以就存它的name,value值存它的长度,这样,length(只保存数据用)可以一样,但是name是不一样的。

 

1.2.4 栈帧

栈帧(Stack Frame)是用于支持函数调用和返回的一种数据结构。每次调用函数时,系统会为该函数分配一个栈帧,栈帧中存储了函数的局部变量、参数、返回地址以及其他与函数调用相关的信息。当函数执行完毕后,栈帧会被释放,以便返回到调用函数的上下文。

栈帧通常包括以下几个重要的部分:

  1. 局部变量区域(Local Variables Area):用于存储函数中定义的局部变量。局部变量只在函数内部可见,函数调用结束后会自动销毁。

  2. 参数区域(Arguments Area):用于存储函数调用时传递的参数。这些参数可以是函数的输入,供函数在执行时使用。

  3. 返回地址(Return Address):用于存储函数执行完毕后要返回的位置。当函数执行完毕时,程序会从返回地址处继续执行。

  4. 调用者的帧指针(Caller's Frame Pointer):指向调用函数的栈帧。它可以用来访问调用函数的局部变量和参数。

  5. 其他上下文信息:可能包括存储寄存器的值、状态信息等。

栈帧的创建和销毁是通过栈(Stack)数据结构来管理的。栈是一种后进先出(Last-In-First-Out,LIFO)的数据结构,适用于函数调用和返回的特性。当函数被调用时,系统将新的栈帧压入栈顶,当函数返回时,对应的栈帧会被弹出。

栈帧的概念在程序执行和调试过程中起着重要的作用,它使得函数的嵌套调用能够正确地保存和恢复上下文信息,保证程序的正确执行和控制流的正确性。

 

 
文章来自个人专栏
mysql-插件
5 文章 | 1 订阅
0条评论
0 / 1000
请输入你的评论
0
0