避免释放字符串字面值



如果你有一个C语言的函数,它接受传入它的任何东西的所有权,比如按值将struct添加到向量缓冲区的函数,并且这个结构体值包含一个指向字符数组(字符串)的成员指针,

在缓冲区的清理过程中,它应该释放它所拥有的字符串,但是如果一些字符串是在运行时分配的,而其他字符串是在编译时使用字符串字面量分配的呢?

没有安全和标准(非专有)的方法来检测char*是否指向只读内存,那么这个假设的freeVector函数与指向字符缓冲区的指针有什么关系?

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
    }
}

C语言的优点和缺点在于它完全由你决定。有两种选择,一种是分配堆上的所有内容,另一种是定义一个胖指针类型,其中包含一个bit来说明每个实例是否需要释放。一个聪明但不可移植的实现可能会使用指针本身的低阶位,因为在许多体系结构中,所有指针的底部2位或更多总是零。垃圾收集器几乎永远使用这个技巧来区分指针和未装箱的离散类型(fixnum)。

如果你允许多个指针指向同一个对象(想想图形数据结构),那么事情就会变得更加复杂或有趣,这取决于你的观点。为此,您可能需要一个垃圾收集方案:阻塞、引用计数、标记和清除、竞技场复制等。其他语言倾向于为您提供其中的一个作为内置或(如c++)语言特性,旨在支持您自己实现一个或多个。

最新更新