2

我仍然对我的 C 生锈了,我只是没有弄清楚这一点。我想做的是实现我自己的 malloc,这样我就可以跟踪分配并调试对 free() 的丢失调用。我有一个这样的标题:

typedef struct MemoryInfo {
  mem_Kind kind;
  unsigned int id;
  struct MemoryInfo* prev;
  struct MemoryInfo* next;
} MemoryInfo;

我的自定义 malloc 看起来像这样:

void* my_malloc(mem_Kind kind, unsigned int size) {
  MemoryInfo* mem;

  allocCount++;
  mem = (MemoryInfo*)malloc(sizeof(MemoryInfo) + size);
  mem->id = id;
  mem->kind = kind;
  // set prev/next...

  return mem + sizeof(MemoryInfo); // return pointer to memory after header
}

但我显然弄错了我的指针算术,因为它很快就爆炸了。但是,如果我将 a 添加void* memory到我的结构的末尾并执行另一个 malloc ,那么它似乎做得很好,问题是my_free如果我这样做我真的无法找到标题。我试图基本上预先添加标题,以便我可以做一些反向指针算法来免费获取标题。

void my_free(void* memory) {
  MemoryInfo* mem = memory - sizeof(MemoryInfo); // not correct either
  allocCount--;
  free(mem);
}

我在这里做错了什么?

4

3 回答 3

1

我认为您在添加指针时遇到问题。它必须是这样的:

return (char*)mem + sizeof(MemoryInfo); // return pointer to memory after header

void my_free(void* memory) {
  MemoryInfo* mem = (MemoryInfo*)((char*)memory - sizeof(MemoryInfo)); // not correct either
  allocCount--;
  free(mem);
}

顺便一提。看看这个程序。

#include <stdio.h>

typedef struct MemoryInfo {
  int kind;
  unsigned int id;
  struct MemoryInfo* prev;
  struct MemoryInfo* next;
} MemoryInfo;



int main()
{
  MemoryInfo* ptr = 0;

  printf("sizeof: %d\n",sizeof(MemoryInfo));
  printf("%d\n",ptr+3);
  return 0;
}

我已将 3 添加到指向 MemoryInfo 的指针,但它的值变为 3*sizeof(MemoryInfo)。

于 2012-05-12T16:45:39.633 回答
0

你的指针算法是错误的。在ptr+1+1 中已经使用了正确的增量(sizeof *ptr)。如果 ptr 是 char 指针,则必须递增sizeof *ptr,但事实并非如此。

void *my_malloc(mem_Kind kind, unsigned int size) {
  MemoryInfo  mem;

  allocCount++;
  mem = malloc(sizeof *mem + size);
  mem->id = id;
  mem->kind = kind;
  // set prev/next...

  return mem + 1; // return pointer to memory after header
}


void my_free(void *memory) {
  MemoryInfo *mem = memory; // not correct either
  mem -= 1;
  allocCount--;
  free(mem);
}

另外,请注意 malloc() 和朋友应该返回一个适合每个对象的指针,并且必须与任何对象的自然边界对齐。(这可能是 32 位、64 位或您的平台规定的任何内容)例如,您的尺寸可能会因 sizeof (int)==2 和 sizeof (void*) == 8 而失败。(但幸运的是,这似乎是一种非常罕见的情况)

于 2012-05-12T17:04:49.953 回答
0

好的做法是这样定义的:

struct some_struct {
  size_t data_size;
  struct some_struct  *next, *prev;
  void * struct_data[];
}

我们就是这样:

struct some_struct *get_some_struct ( void *buf,size_t buflen,struct some_struct **next){
  *next=0;
  struct some_struct *s=(struct some_struct *)buf;
  if ( s && buflen < sizof(*s) + s->data_size )
    *next = (char*)s + s->data_size;
    return s;
  else
    return 0;
}

因此,如果您需要遍历结构,您可以正确获取缓冲区中下一个结构的偏移量。我只是想让你得到方法。如果你能得到它会很高兴

于 2012-05-12T18:05:59.127 回答