2012-07-30 70 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