Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/opengl/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
是否有一个malloc实现在自己的堆之外进行簿记?_C_Opengl_Embedded_Malloc - Fatal编程技术网

是否有一个malloc实现在自己的堆之外进行簿记?

是否有一个malloc实现在自己的堆之外进行簿记?,c,opengl,embedded,malloc,C,Opengl,Embedded,Malloc,我需要管理一个内存堆,但有一个约束条件,即该内存只能写入,不能读取,即malloc实现应该将簿记信息与它管理的堆分开保存在普通堆上,并且实际上永远不要接触它管理的特定堆。我希望使用经过测试、优化、现成的解决方案(如果有的话)。使用示例包括OpenGL VBOs和嵌入式系统外部单元上的内存 我浏览了一下dlmalloc,从文档中可以看出,它似乎用簿记信息标记了从两侧分配的内存块。谷歌搜索也没有任何好处——也许我没有合适的关键字来找到我要找的东西 澄清:作为一个单独的堆,我指的是我定义的堆。我希望在

我需要管理一个内存堆,但有一个约束条件,即该内存只能写入,不能读取,即malloc实现应该将簿记信息与它管理的堆分开保存在普通堆上,并且实际上永远不要接触它管理的特定堆。我希望使用经过测试、优化、现成的解决方案(如果有的话)。使用示例包括OpenGL VBOs和嵌入式系统外部单元上的内存

我浏览了一下dlmalloc,从文档中可以看出,它似乎用簿记信息标记了从两侧分配的内存块。谷歌搜索也没有任何好处——也许我没有合适的关键字来找到我要找的东西

澄清:作为一个单独的堆,我指的是我定义的堆。我希望在一个或一小部分预先分配的块中通过小的分配紧密地使用内存。我甚至不在乎簿记信息(在这样管理的堆之外)是否大于堆内的数据:)此外,应用程序本身将使用stock malloc和heap进行操作,并且仅将这些块用于特殊目的,这归结为与外部硬件对话的内存区域,当应用程序的写入是目的时,读取是不可能的或昂贵的。这不是一个一般的malloc问题,我只是希望利用一些已经进行了大量研究和测试的东西

事实上,不应该触及它所管理的特定堆

如果它不管理堆呢?请参阅此malloc函数,它使用的特定实现既不管理[heap]区域(参见
/proc/$$/maps
),也不将其元数据存储在可寻址内存中,但为程序提供了唯一的可寻址内存

void *mymalloc(size_t len) { void *x = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); return (x == (void *)-1) ? NULL : x; } void*mymalloc(尺寸长度) { void*x=mmap(NULL,len,PROT_READ | PROT_WRITE,MAP_PRIVATE | MAP_ANONYMOUS,-1,0); 返回值(x==(void*)-1)?空值:x; }
现在是致命的启示:glibc正是使用它来进行足够大的分配。

这里有一个非常简单的
malloc
实现,它从不将簿记信息写入它所管理的堆:

void *malloc(size_t n) { return sbrk(n); }
void free(void *p) { }
void *realloc(void *p, size_t n }
{
    void *q = malloc(n);
    if (q) memcpy(q, p, n);
    return q;
}

如果您想要一些更现实的想法,一个简单的解决方案是选择一个最小的内存单元进行分配(8或16字节可能是合理的),并将托管堆划分为这个大小的单元,然后将哪些是空闲的存储在位图中(例如,对于1/128,每16字节一位,实现可能相当简单。不使用分配的块存储metatdata的一个缺点是free()的性能可能较慢且不确定。但由于malloc()已经存在该问题,这可能不是真正的问题


一个简单的确定性解决方案是实现一个固定块内存分配器,其中固定大小的块从传统堆中分配,指向每个块的指针放在队列或链表上。要分配块,只需从空闲块队列/列表中取一个指针,然后将指针放回空闲块上即可ck list。

它不是一个现成的库,但Linux内核中的代码正是这样做的,以管理资源,如PCI地址空间。

管理器是否需要与malloc/free具有相同的语义?如果您能让分配函数返回指向结构的指针,那么事情就会大大简化,而该结构反过来会int表示实际内存;deallocate函数将接受指向结构的指针,而不是指向内存的指针


除此之外,分配方法将受到您的使用模式的极大影响。关于分配的大小以及分配和释放内存块的模式,可以说些什么?

只要使用。

/dev/null是一个很好的只写数据存储。我假设您的意思是只有堆管理器不读取内存。我有一个问题在应用程序本身无法读取其写入的内存的情况下,我很想知道这个功能背后的需求——可能还有另一种方式。事实上,应该永远不要接触它管理的特定堆——那么它是如何管理的呢?所以你希望内存损坏不会影响簿记数据吗?
*(int*)rand()=rand()
?除非它完全在内核中,否则你永远无法确定。那么“死亡比残废好”的原则呢?@detly:他的意思是将元数据与可分配内存块分开。glibc没有(也不能)对于较大的分配,请使用该方法,因为您的方法会丢弃映射的大小。因此,以后不可能释放它。glibc将该大小存储在映射的开头,并返回一个指向刚好超出该大小的内存的指针。哦,当然,实现起来很简单!很难做到完美,而且我相信有人在我之前就这样做了,现在看30在malloc多年的研究、实施和测试历史中,我希望能在那里钓鱼。我对realloc会有点不舒服。如果malloc失败,您的分配将没有所需的额外空间。