避免释放字符串文字
Avoiding freeing a string literal
如果您在 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 的祝福和诅咒是它让这完全取决于你。两种选择是在堆上分配所有内容并定义一个胖指针类型,其中包含一个位来说明每个实例是否需要释放。一个聪明但不可移植的实现可能会使用指针本身的低阶位,因为对于许多体系结构,所有指针的底部 2 位或更多位始终为零。垃圾收集器几乎永远使用这个技巧来区分指针和未装箱的离散类型(fixnum
s in the biz)。
如果您允许多个指针指向同一对象(想想图形数据结构),那么事情会变得更加复杂或有趣,具体取决于您的观点。为此,您可能需要一个垃圾收集方案:障碍、引用计数、标记和清除、竞技场复制等。其他语言往往会故意为您提供其中之一作为内置或(如在 C++ 中)语言功能旨在支持自己实施一个或多个。对于 C,没那么多...
如果您在 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 的祝福和诅咒是它让这完全取决于你。两种选择是在堆上分配所有内容并定义一个胖指针类型,其中包含一个位来说明每个实例是否需要释放。一个聪明但不可移植的实现可能会使用指针本身的低阶位,因为对于许多体系结构,所有指针的底部 2 位或更多位始终为零。垃圾收集器几乎永远使用这个技巧来区分指针和未装箱的离散类型(fixnum
s in the biz)。
如果您允许多个指针指向同一对象(想想图形数据结构),那么事情会变得更加复杂或有趣,具体取决于您的观点。为此,您可能需要一个垃圾收集方案:障碍、引用计数、标记和清除、竞技场复制等。其他语言往往会故意为您提供其中之一作为内置或(如在 C++ 中)语言功能旨在支持自己实施一个或多个。对于 C,没那么多...