C 内存池存储
我正在写小型内存分配系统。具有:C 内存池存储,c,pointers,memory,memory-management,C,Pointers,Memory,Memory Management,我正在写小型内存分配系统。具有: typedef struct _POOL { int size; /*size of memory pool*/ void* memory; /*pointer to pool location in memory*/ } Pool; Pool* allocatePool(int n) { Pool *myPool = malloc(sizeof(Pool) + n); if (myPool){ myP
typedef struct _POOL
{
int size; /*size of memory pool*/
void* memory; /*pointer to pool location in memory*/
} Pool;
Pool* allocatePool(int n) {
Pool *myPool = malloc(sizeof(Pool) + n);
if (myPool){
myPool->size = n;
myPool->memory = myPool+1;
}
return myPool;
}
我正在尝试编写一个函数,该函数将在池中的位置偏移处存储任意大小为n的对象
void store(Pool* pool, int offset, int size, void *object) {
char *ptrHelper;
ptrHelper = &(pool->memory); /*copy pool memory address*/
ptrHelper += offset; /*increment to match offset*/
memcpy(ptrHelper, &object, size); /*copy object in to the pool*/
}
问题:
ptrHelper=&(pool->memory)是否有其他获取池内存地址的正确方法
如果我想存储大于void*对象大小的值(我的情况下为4字节),该怎么办
如何在不改变函数参数结构的情况下正确处理字符串?
谢谢。ptrHelper=&(池->内存)
没有给出池内存地址。
使用:
ptrHelper=pool->memory
我不确定这是最好的答案,但这可能会有帮助……:
store
函数误用了指针。例如:对象
已经是指针,请直接使用它(不要使用指针的地址)。这同样适用于ptrHelper
——它已经是一个指针了
获取指针地址(使用和运算符)将返回指针在堆栈内存地址中的位置(函数中变量的位置),而不是数据的位置
size
类型更改为size\u t
,这是您从size\u of
中得到的,也是malloc
所期望的
如果它对您来说太大,您可以使用无符号int或无符号short,这取决于您将使用的上限。。。然而,这将使错误处理变得更难管理size
属性并使用FAM(灵活数组成员)的相同结构:
这一微小的变化也使分配更加容易:
Pool* allocatePool(size_t n) {
Pool *myPool = malloc(sizeof(Pool) + n);
if (myPool){
myPool->size = n;
}
return myPool;
}
需要考虑的是—此结构和分配函数要求池
对象的用户使用特殊语义访问内存
另一方面,返回pool->memory
数组而不是pool
对象将允许您的用户不可知,并且您可以实现一个直接适用的malloc
替代方法
当返回指针时,只需计算偏移量即可找到原始池
对象在内存中的位置
看看Redis使用的神奇工具吧——它们有很棒的想法
您可以使用以下方法实现类似的功能:
#define _get_pool_addr(p) ((p) - sizeof(Pool))
void* allocatePool(size_t n) {
Pool *myPool = malloc(sizeof(Pool) + n);
if (myPool){
myPool->size = n;
}
return myPool->memory;
}
void freePool(void * pooled_memory) {
Pool *myPool = _get_pool_addr(pooled_memory);
// do what you want. If you're freeing the memory:
free(myPool);
}
使用这些更改,您的store
功能非常直接:
void store(void * mymem, int offset, int size, void *object) {
memcpy(mymem + offset, object, size); /*copy object in to the pool*/
}
我认为这比使用一个类似这样的store
函数要好(您的版本,刚刚修复):
祝你好运 为什么
&(池->内存)
而不是池->内存
?似乎pool->memory
已经是指向池的指针。为什么取它的地址?如果偏移量
为0,是否覆盖池->内存
?池->内存是我池的基址。增加它的地址会更改我的池的地址,而将offset设置为0不会更改我的目标地址。我可能错了。这是我进入C:)的第一步。这是第二次重新发布!仅供参考:我将其标记为mod注意。堆栈溢出不是教程站点。如果你缺乏基础知识,请阅读一本C语言书,先从一些更容易练习的东西开始。@Olaf我和版主谈过我的帖子。我们得出结论,我应该删除以前的帖子,重新措辞我的问题。是的。你应该在你的问题中提到这一点。不管怎样,我们将看看mod做了什么;我仍然认为你的问题过于宽泛(显然我不是唯一一个)。无意冒犯(老实说!),但您确实应该首先在C语言中进行更多的练习,并学习如何在C语言中做一些事情。内存管理包括许多不严格符合标准的操作,初学者应该避免这些操作。我已经看到了各种各样的问题。而你的代码在某些部分是不一致的,这实际上是应该的!虽然付出了不少努力,但仍然存在一些缺陷。对于初学者:混合有符号整数和无符号整数应该非常小心地处理。sizeof
运算符生成一个size\u t
,它不应与int
混合使用。总的来说,做OP的工作是个坏主意。最好给出一些提示并解释她遇到的问题,这样他就可以自己编写代码了。否则,他将无法真正学习。“使用未命名结构”-没有“未命名结构”。@Olaf-谢谢。我刚刚修复了与问题相关的部分(而不是int
v.ssize\u t
),因此感谢您的关注。至于OP的工作。。。我认为他/她已经完成了大部分工作,只是在指针使用方面有问题(我忽略了类型不匹配)。。。但是下次我会记住的。我觉得这个问题没有多大用处。这不是内存管理,只是向分配的块添加不必要的大小。不必要,因为free
不需要它。顺便说一句,你的代码也错了。void*
上的算术未定义。还有其他未定义的行为与对齐问题。如果函数可以执行相同的任务,也不要使用宏。如果对性能有疑问(大多数情况下,早期代码是个坏主意),请将其设置为静态
和/或内联
@Olaf-谢谢!我想,通过这个答案,我学到了比提问者更多的东西:——)
void store(void * mymem, int offset, int size, void *object) {
memcpy(mymem + offset, object, size); /*copy object in to the pool*/
}
void store(Pool* pool, int offset, int size, void *object) {
char *ptrHelper;
ptrHelper = pool->memory; /*copy pool memory address*/
ptrHelper += offset; /*increment to match offset*/
memcpy(ptrHelper, object, size); /*copy object in to the pool*/
}