找回密码
 立即注册→加入我们

QQ登录

只需一步,快速开始

搜索
热搜: 下载 VB C 实现 编写
查看: 1278|回复: 18

【VB6】最简单的“栈”演示

[复制链接]
发表于 2022-5-12 00:17:31 | 显示全部楼层 |阅读模式

欢迎访问技术宅的结界,请注册或者登录吧。

您需要 登录 才可以下载或查看,没有账号?立即注册→加入我们

×
栈是一个“先进后出”的数据结构,非常类似现实世界中的弹匣(第一发压入的子弹最后一发射出)。实际应用举例:做多标签浏览器时,每关闭一个TAB之前,就把TAB的URL记录一下;如果用户按下CTRL+SHIFT+T,就重新打开刚才被关闭的页面。利用VB自带的动态数组,可以用极少的代码实现栈结构。把下面的代码保存在FRM文件后,双击打开即可运行。DEMO里的PUSH按钮是压栈,每次给栈里压入一个数字;POP按钮是弹栈,一次性把栈里的内容全部弹出。
.png
游客,如果您要查看本帖隐藏内容请回复
回复

使用道具 举报

发表于 2022-5-12 09:24:10 | 显示全部楼层
此处可以顺带讨论一下 Java 和 C# 的堆内存管理。虽然是堆,但是长得像栈一样,你 new 的时候,相当于从栈上 push;但是你不需要 delete,因此没有 pop。当空间满了的时候,GC 触发,暂停线程,然后从线程上下文寄存器、栈上的局部变量、堆上结构体和类里面的成员变量里进行扫描,找出所有的指针,其指向内容被标记为“正在被使用”,其余的就是要被回收的“垃圾”了,然后把所有正在被使用的数据 memcpy 到“起点”,并且重新计算所有的指针值,再赋值回去,然后再恢复所有被暂停的线程的运行。
回复 赞! 靠!

使用道具 举报

发表于 2022-5-13 15:34:34 | 显示全部楼层
如此好贴,必须支持~~~
回复 赞! 靠!

使用道具 举报

发表于 2022-5-13 21:20:28 | 显示全部楼层
0xAA55 发表于 2022-5-12 09:24
此处可以顺带讨论一下 Java 和 C# 的堆内存管理。虽然是堆,但是长得像栈一样,你 new 的时候,相当于从栈 ...

站长研究过伙伴系统没,伙伴系统是一种巧妙地内存管理系统,虽然不能完全消除内存你碎片,但能很大程度上减少内存碎片的产生。
回复 赞! 靠!

使用道具 举报

发表于 2022-5-13 22:31:11 | 显示全部楼层
usr 发表于 2022-5-13 21:20
站长研究过伙伴系统没,伙伴系统是一种巧妙地内存管理系统,虽然不能完全消除内存你碎片,但能很大程度上 ...

没有。细说?
回复 赞! 靠!

使用道具 举报

发表于 2022-5-13 23:35:32 | 显示全部楼层
本帖最后由 usr 于 2022-5-13 23:46 编辑


BuddySystem.png
请看这张图。

简而言之,伙伴系统就是把给定的内存一半一半劈开,将大小合适的一半分配出去。回收内存时将空闲的两半合并。
回复 赞! 靠!

使用道具 举报

发表于 2022-5-14 22:18:37 | 显示全部楼层
usr 发表于 2022-5-13 23:35
请看这张图。

简而言之,伙伴系统就是把给定的内存一半一半劈开,将大小合适的一半分配出去。回收内存 ...

现有的 C 标准库的 malloc 在底层貌似已经是这样的实现了。
回复 赞! 靠!

使用道具 举报

 楼主| 发表于 2022-5-15 08:58:10 | 显示全部楼层
0xAA55 发表于 2022-5-14 22:18
现有的 C 标准库的 malloc 在底层貌似已经是这样的实现了。


我似乎感觉,malloc和VirtualAlloc分配的不是同一种内存,这俩函数不能混用(不能“用malloc申请,用VirtualFree释放”)。

此外,一些远古时代的程序还用HeapAlloc/HeapFree,话说这玩意是啥?
回复 赞! 靠!

使用道具 举报

发表于 2022-5-15 09:03:11 | 显示全部楼层
xuexixuexi
回复 赞! 靠!

使用道具 举报

发表于 2022-5-15 13:42:46 | 显示全部楼层
美俪女神 发表于 2022-5-15 08:58
我似乎感觉,malloc和VirtualAlloc分配的不是同一种内存,这俩函数不能混用(不能“用malloc申请,用Virt ...

VirtualAlloc 分配下来的内存按页算,而 malloc 分配下来的内存按字节算。事实上,malloc 是从 VirtualAlloc 分配下来的内存里分配内存。

HeapAlloc 和 HeapFree 可以理解为一种私有内存池,它的分配释放可以在堆的内部管理,不用干涉整个进程内存空间。
回复 赞! 靠!

使用道具 举报

发表于 2022-5-15 23:19:51 | 显示全部楼层
美俪女神 发表于 2022-5-15 08:58
我似乎感觉,malloc和VirtualAlloc分配的不是同一种内存,这俩函数不能混用(不能“用malloc申请,用Virt ...

VirtualAlloc直接走内核,分配的粒度按页对齐,可以直接在进程的VAD树里找到。VAD树是AVL的二叉树,按地址排序,保障平衡,找起来很快。
malloc不会走到内核,除非堆内存不足。分配的对齐粒度看堆,比如Win32的8字节,Win64的16字节。
详情见Chapter 5 "Memory Management", Windows Internals (Part 1), 7th Edition.
回复 赞! 靠!

使用道具 举报

发表于 2022-5-18 02:22:38 | 显示全部楼层
刚开始学 不知道能不能看懂 看了再说
回复 赞! 靠!

使用道具 举报

 楼主| 发表于 2022-5-18 17:59:37 | 显示全部楼层
0xAA55 发表于 2022-5-15 13:42
VirtualAlloc 分配下来的内存按页算,而 malloc 分配下来的内存按字节算。事实上,malloc 是从 VirtualAl ...

WINDOWS的“堆”实际上是啥呢?不可能是CPU的内部存储器(比如缓存)吧,我感觉其实还是内存啊。
回复 赞! 靠!

使用道具 举报

 楼主| 发表于 2022-5-18 18:00:27 | 显示全部楼层
tangptr@126.com 发表于 2022-5-15 23:19
VirtualAlloc直接走内核,分配的粒度按页对齐,可以直接在进程的VAD树里找到。VAD树是AVL的二叉树,按地 ...


“堆内存”?换句话说,malloc和free实际上是HeapAlloc和HeapFree?
回复 赞! 靠!

使用道具 举报

发表于 2022-5-18 19:57:24 | 显示全部楼层
美俪女神 发表于 2022-5-18 18:00
“堆内存”?换句话说,malloc和free实际上是HeapAlloc和HeapFree?

堆就是Heap。通常来说,malloc的最终实现就是HeapAlloc
一般说申请内存就分为从堆上分配(malloc)和从栈上分配(alloca或者局部变量)。
前者是运行时的,涉及多线程,分配要获取锁,速度比较慢。
后者是编译时的,无关多线程,只需要对esp/rsp作减法即可,速度很快。
通常来说,为了高性能地给多线程分配堆内存,设计者会提前创建多个堆,保证线程之间不会因为分配堆内存而造成等待。

回复 赞! 靠!

使用道具 举报

 楼主| 发表于 2022-5-18 21:46:08 | 显示全部楼层
tangptr@126.com 发表于 2022-5-18 19:57
[md]
堆就是Heap。通常来说,`malloc`的最终实现就是`HeapAlloc`。
一般说申请内存就分为从堆上分配(`ma ...


我忽然明白为啥有些古老程序用HeapAlloc而不是VirtualAlloc了。

在上古时代内存也就16到64MB,VirtualAlloc一下,可用内存就少了4KB,多VirtualAlloc几下,内存就用完了。而大多数情况下,申请内存也就需要几十到几百字节而已(路径、结构体等),所以用HeapAlloc是最佳选择。

后来随着内存越来越大,现在的内存普遍是16到64GB,所以也就没人在乎HeapAlloc和VirtualAlloc的区别了。
回复 赞! 靠!

使用道具 举报

发表于 2022-5-19 09:29:00 | 显示全部楼层
牛逼,支持!
回复

使用道具 举报

发表于 2022-5-19 12:35:30 | 显示全部楼层
美俪女神 发表于 2022-5-18 17:59
WINDOWS的“堆”实际上是啥呢?不可能是CPU的内部存储器(比如缓存)吧,我感觉其实还是内存啊。 ...

就是内存。
回复 赞! 靠!

使用道具 举报

发表于 2022-5-24 17:28:05 | 显示全部楼层
学习学习
回复

使用道具 举报

本版积分规则

QQ|Archiver|小黑屋|技术宅的结界 ( 滇ICP备16008837号 )|网站地图

GMT+8, 2024-12-22 11:04 , Processed in 0.040328 second(s), 25 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表