提问人:user129393192 提问时间:6/13/2023 最后编辑:user129393192 更新时间:6/13/2023 访问量:105
如何分配和管理自己的堆(非动态分配)?
How can I allocate and manage my own heap (not dynamically allocating)?
问:
我有一个程序,分配我自己的堆对我来说是有意义的,因为我有一个特定的读取操作,可能会占用一些不确定的空间量,我需要连续存储到内存中,以便于使用。我知道这为和朋友设置了一堆,并且那个电话可能会搞砸它。我不打算在我的程序中使用或以其他方式使用堆。libc
malloc
sbrk
brk
malloc
简单地说,我想要一个类似“堆”的内存区域,在那里我可以请求操作系统根据需要增加它,并且它不受文件系统的支持。
即使只是为了学习目的,我如何:
- 防止堆设置方式
libc
- 设置我自己的堆
- 使用和
sbrk
brk
答:
0赞
12431234123412341234123
6/13/2023
#1
正如评论中所说,你不应该这样做。如果数据来自文件,则可以像访问任何其他内存一样映射文件并访问它。然后,内核会处理程序可访问的从磁盘到 RAM 的读取。如果无法做到这一点,则可以对于少量数据,使用足够大的缓冲区,并在需要更多缓冲区时使用。如果数据太大,以至于速度太慢,最好编写一个类来处理对数组的读写访问,并且不连续存储数组。mmap()
realloc()
但是可以编写自己的堆。您可以使用它来保留内存,并在需要时扩展内存。
您可以像这样保留它:mmap()
long ps = sysconf(PAGESIZE);
if(ps<0) { /*TODO handle error*/ return -1; }
*start = mmap(NULL,ps*1024,PROT_READ|PROT_WRITE,MAP_PRIVATE|MAP_ANONYMOUS,-1,0);
if(!start) { /*TODO handle error*/ return -1; }
//Here you have 1024*ps space to handle your own malloc
的值并不意味着您的应用程序实际上使用了那么多内存,页面保留是惰性的,这意味着只有在应用程序尝试读取或写入它之后才会保留。1024*ps
在 Linux 上,您还可以通过调用 来扩展空间。但这可能不起作用,例如,当相同的内存已经在其他地方使用时。
该提案还存在其他问题。mremap()
要了解更多信息,请使用 .man mmap
评论
0赞
Andrew Henle
6/13/2023
但这可能不起作用,例如,当相同的内存已经在其他地方使用时。 它不仅会起作用,还会踩踏任何东西:“mmap() 建立的映射将替换那些包含进程地址空间任何部分的整个页面的任何先前映射,从 pa 开始,一直持续到 len 字节。
0赞
12431234123412341234123
6/13/2023
@AndrewHenle 正确,编辑它以建议避免这种情况(AFAIK 它不会遇到同样的问题)。mremap()
0赞
Andrew Henle
6/14/2023
mremap()
不是 POSIX,尽管我认为没有一种完全符合 POSIX 的方法来保证连续内存。 例如,获得有保证的映射地址不是 POSIX,它是一个扩展,尽管是一个常见的扩展。尽管我认为在这一点上可能完全没有意义 - 我上面的最后一条评论指出了任何尝试处理泛型流的两遍算法中的致命缺陷:不能保证泛型流是可寻的。MAP_FIXED
评论
realloc
realloc
realloc