【问题标题】:C custom malloc function not reading block sizeC自定义malloc函数不读取块大小
【发布时间】:2016-06-23 18:31:02
【问题描述】:

我尝试实现一个自定义的 malloc 函数。我对尺寸部分有疑问。由于我们可以释放变量,因此可以重新分配空白空间。自定义结构为 32 位长,包含数据的大小和一个布尔值(无符号 int 免费:1),表示数据是否空闲。

这是我的 malloc 函数:

void *mymalloc(size_t size) {
if (!size) return NULL;
size_t length = align(size + sizeof(struct header));
Header current = availableHeader(size);
if (!(current==sbrk(0))) {
    Header newHeader = sbrk(length);
    if (newHeader == (void*) -1) {
        return NULL;
    }
    newHeader->size = length - sizeof(struct header);
    current = newHeader;

} else if (length + sizeof(size_t) < current->size) {

    split(current, length);
}
current->free = 0;
return current+sizeof(struct header);
}

这使用了一个名为“availableHeader”的函数,它将找到第一个可用内存,如果没有其他可用内存并且有足够的大小来存储数据,则会找到一个新内存。

Header availableHeader(size_t s) {
Header current = firstHeader();
int isHeader=1;
for (;isHeader && (!current->free || current->size < s); current = current+current->size+sizeof(struct header)){
    printf("%d on %d for %d\n", current->free, current->size, s);//TEST
    if(current>=sbrk(0)){
        isHeader=0;
    }
}
return current;
}

最后,这个函数使用“firstHeader”返回我们创建的第一块,如果是第一次调用,它会创建第一个。

static void *firstHeader() {
static Header b = NULL;
if (!b) {
    b = sbrk(align(sizeof(struct header)));
    if (b == (void*) -1) {
        _exit(127);
    }
    b->size = 0;
    b->free = 0;       
}
return b;
}

现在,问题是“availableHeader”永远不会返回已经创建的块。它总是导致创建一个新的,这是一种糟糕的内存管理策略。 通过测试(标记为//TEST)我看到我在“availableHeader”中的循环总是看到当前内存块的大小和空闲都是“0”。

即使有这一行,我的 malloc 函数似乎也从未设置大小:

newHeader->size = length - sizeof(struct header);

但问题仍然存在:读取“availableHeader”中的大小会返回 0,即使它有另一个值。

编辑: 根据要求,这是结构:

struct header {
    unsigned int size : 29,
                 zero :  2,
                 free :  1;
};

【问题讨论】:

  • 您确定正确创建了标题结构吗?可以出示声明吗?
  • 我编辑了结构。
  • static Header b = NULL; -->> static Header *b = NULL; 也许?
  • current+sizeof(struct header); 指针算术错误。

标签: c malloc


【解决方案1】:

当您的availableHeader 返回一个指向可以重用的标头的指针(free == 1 &amp;&amp; size &gt;= s) 您的mymalloc 函数会命中if (!(current==sbrk(0))),因为当前不在程序中断处。 False 否定 true 并且您分配新内存而不是重用旧内存。

【讨论】:

  • 这可能是另一个问题的解决方案。但现在,我无法检索 size 属性。由于 availableHeader 无法读取已检查标题的大小,因此它无法“正确”转到下一个。要遍历标头,我的函数应该添加 32 位(sizeof 标头)+ X 位,其中 X 是大小属性。但由于它无法检索大小,因此“当前”标头不是标头。
  • 当然不能。检查指针算法是如何工作的。 Current + 10 并不意味着移动 10 个字节,而是移动被引用对象大小的 10 倍。输入到(void *)
  • 谢谢。我编写了我的代码,但在那之后我陷入了困境,我决定从头开始。但是通用指针有很大帮助!谢谢。
  • @PeterSilon 指向 (void *) 的指针算术在标准 C 中是不允许的。(您使用它可能是 GCC 的扩展)sample code
猜你喜欢
  • 2016-05-07
  • 1970-01-01
  • 2020-12-06
  • 2011-04-07
  • 1970-01-01
  • 2023-02-16
  • 1970-01-01
  • 1970-01-01
  • 2014-08-06
相关资源
最近更新 更多