2012-07-30 58 views
1

只是为了好玩(和C编程实践),我写了下面这段代码执行以下操作:C中的内存分配跟踪 - 我做对了吗?

  • 充当内存分配跟踪系统
  • 释放所有动态与函数调用分配的内存

下面是代码:

typedef enum _OpMode { 
    OM_APPEND, 
    OM_DESTROY 
} OP_MODE; 

void refOp(void *ptr, OP_MODE mode) { 
    /* contains static array of pointers and provides an interface to that 
     array */ 

    static void **references = NULL; 
    static int size = 0; 
    static int reset = 0; 

    if (reset) { 
     reset = 0; 
     references = NULL; 
     size = 0; 
    } 

    switch (mode) { 
     case OM_APPEND: 
      //add a pointer to reference array 
      references = (void**) realloc(references, sizeof(void*) * (size + 1)); 
      references[size++] = ptr; 
      break; 
     case OM_DESTROY: 
      //free memory at all pointers kept in reference array 
      for (int i = 0; i < size; i++) { 
       free(references[i]); 
       references[i] = NULL; 
      } 
      free(references); 
      reset = 1; 
      break; 
     default: 
      printf("Invalid enum value '%d' passed as mode.\n", mode); 
      break; 
    } 
} 

void refDestroyAll() { 
    //Wrapper function 
    refOp(NULL, OM_DESTROY); 
} 

void *myAlloc(void* ptr, size_t size) { 
    /* Allocates memory and stores pointer copy in reference array */ 
    void *tmp_ptr; 
    tmp_ptr = realloc(ptr, size); 
    refOp(tmp_ptr, OM_APPEND); 
    return tmp_ptr; 
} 

的想法是,一个会用myAlloc()而不是mallocrealloc来动态分配内存。然后使用refDestroyAll()释放所有使用myAlloc()创建的内存。

我已经做了一些测试,它似乎工作,但我不禁觉得我失去了一些重要的东西。这段代码实际上是否按照预期工作,或者我打电话给refDestroyAll()时是否在泄漏内存?

+3

也许你可以追踪一些性能分析工具的源代码,比如valgrind http://valgrind.org/。 – qrtt1 2012-07-30 02:40:20

+0

对于你正在做的事情,只要在你的代码上运行valgrind本身就会让你知道你是否从'refDestroyAll()泄漏了内存......你不需要检查valgrind的源代码。 – Jason 2012-07-30 02:50:08

+0

@ qrtt1:感谢valgrind链接。我现在只是测试我的程序。 – 2012-07-30 03:18:18

回答

1

您有一个错误,可能会导致分段错误。 realloc()可能会返回与给定的指针相同的指针,在这种情况下,您会将其添加到数组两次。当您调用免费函数时,它会尝试释放相同的指针两次,导致分段错误错误。

此外,我不明白你为什么有重置参数。为什么不简单地在OM_DESTROY的情况下将参考和大小设置为0?释放它后,始终将指针设置为NULL 立即是一种好习惯。

+0

所以你是说如果我在同一个数组上执行两次'myAlloc',然后调用'refDestroyAll',它会在断开对该指针的第二次引用的同时发生段错误? – 2012-07-30 05:05:34

+0

我想我可以通过定义两个alloc函数myMalloc(替换'malloc')和'myRealloc'(替换'realloc')来解决这个问题。这样,如果指针值不相等,我只在'myRealloc'中添加一个项目。这听起来合理吗?还是我仍然错过了这一点?此外,您有关复位参数的权利,这是不必要的。 – 2012-07-30 05:07:26

+0

这样做可行,但它有可能会减慢一个非常大的程序,因为每次调用realloc时都必须执行O(n)搜索。 – charliehorse55 2012-07-30 12:05:18