第三方环形缓冲区实现中元素内存分配位置(栈/堆)的技术问询
环形缓冲区内存分配:MTCircularBuffer vs Embedded_RingBuf_CPP
嘿,我来帮你拆解这两个开源环形缓冲区库的内存分配逻辑,直接看核心实现细节就能搞明白:
MTCircularBuffer
这个库的内存分配分两种场景,完全取决于你初始化缓冲区的方式:
- 默认/指定大小初始化:如果你用的是类似
MTCircularBuffer<int> buf(10);的构造方式,库内部会通过new操作符在堆上分配存储元素的内存块。翻源码就能看到,构造函数会判断如果没有传入外部内存指针,就自动调用new T[size]开辟堆空间。 - 外部内存传入初始化:要是你自己预先准备了一块内存(不管是栈上的数组还是堆上的),再通过构造函数传入,比如:
那元素就会存在你指定的内存区域里——这里就是栈上。int stack_buf[10]; MTCircularBuffer<int> buf(stack_buf, 10);
你运行的测试程序如果用的是第一种初始化方式,那元素肯定是在堆上的。
Embedded_RingBuf_CPP
这个库是专为嵌入式场景设计的,它本身不会主动分配内存,而是要求用户提前准备好存储元素的缓冲区。也就是说:
- 如果你给它传的是栈上的局部数组:
那元素就存在栈上;int stack_buf[20]; RingBuf<int, 20> buf(stack_buf); - 如果你传的是用
new或者malloc在堆上分配的数组,那元素就存在堆上; - 要是传全局/静态数组,元素会落在全局存储区。
测试程序里一般为了简单,会用栈上的数组来初始化,所以你看到的测试场景大概率是栈上分配,但本质是由用户决定的。
亲手验证小技巧
要是你想自己确认,有几个简单方法:
- 对比地址:在Ubuntu上,栈内存地址通常比堆内存高(栈从高地址向下增长,堆从低地址向上),打印缓冲区的存储指针地址,和局部栈变量、堆变量的地址对比就能区分;
- 用
valgrind:运行测试程序时加valgrind --leak-check=full ./test,如果MTCircularBuffer用了堆分配,会显示对应的内存分配和释放记录; - 查源码:直接搜两个库构造函数里的
new、malloc关键字,或者是否有接收外部内存指针的参数。
内容的提问来源于stack exchange,提问作者tauseef_CuriousGuy
相关产品推荐
相关产品推荐

