2015-09-19 110 views
2

如果在C一個函數,無論傳遞到它,諸如,增加了一個struct由-值的向量緩衝區的功能的所有權,並且該結構值包含一個成員的指針一個字符數組(一個字符串)。避免釋放字符串文字

在緩衝區的清理程序,它應該釋放它擁有的字符串,但如果某些字符串在運行時分配的,但是別人都在用字符串常量在編譯時分配的。

沒有安全和標準(非專有)的方式來檢測char*指向只讀內存,那麼這個假設的freeVector函數如何處理指向char緩衝區的指針呢?

struct Element { 
    int id; 
    char* name; 
} 

struct Vector { 
    size_t maxIndex; 
    size_t length; 
    struct Element buffer[]; 
} 

void addToVector(struct Vector* vector, struct Element element) { 
    // lazy-reallocation logic here if maxIndex => length 
    vector->buffer[ vector->maxIndex++ ] = element; // by-value copy 
} 

void freeVector(struct Vector* vector) { 
    for(size_t i = 0; i < vector->maxIndex; i++) { 
     free(vector->buffer[ i ].name); // segfault/AV if name is a literal 
    } 
} 
+0

你的元素結構需要一個標誌,讓你知道你是否能釋放該名與否。 –

+0

@AlexisWilke很好,是的,但我想知道是否有更好的方法。 – Dai

+0

有專有的方法可以知道指針是在堆中還是在啓動數據中,但它可能比較慢(在Unix下,它只是一個指針比較,但Windows需要API調用......)因爲你說「非-proprietary」 ... –

回答

2

C的祝福和詛咒是讓它完全取決於你。兩種選擇是分配堆上的所有內容並定義一個胖指針類型,其中包含一點點來說明每個實例是否需要釋放。一個聰明的,儘管不可移植的實現可能會使用指針本身的低位位,因爲對於許多架構,所有指針的底部2位或更多位始終爲零。垃圾收集器已經使用這個技巧幾乎永遠地將指針與未裝箱的離散類型(商業中的fixnum)區分開來。

如果允許一個以上的指針指向同一個對象(圖認爲數據結構),那麼事情取決於你的觀點變得更加複雜和有趣。爲此,您可能需要一個垃圾回收機制:obstacks,引用計數,標記和掃描,競技場複製等。其他語言傾向於將它們中的一個作爲內置或(在C++中)語言功能意味着支持實施一個或多個自己。隨着C,沒有那麼多...