【发布时间】:2019-11-30 19:35:00
【问题描述】:
我正在准备考试,我对提供给我的样题有疑问:
使用原型
void free_array(void *a[], int length)实现函数free_array。该函数的目的是释放与传递给函数的第一个参数中的每个数组元素相关联的动态分配的内存。该函数必须处理两个或多个数组条目指向同一内存的情况(只有一个空闲可以应用于单个内存位置)。
我的第一个想法是将每个已释放的索引设置为 NULL,因为在 NULL 上调用 free() 是无害的。所以我做了以下事情:
void free_array(void *a[], int length) {
int i;
for (i = 0; i < length; i++) {
free(a[i]);
a[i] = NULL;
}
}
提供的解决方案与我的完全不同,我不完全理解他们在做什么。这是我得到的答案:
void free_array(void *a[], int length) {
int i, j;
for (i = 0; i < length; i++) {
if (a[i] != NULL) {
free(a[i]);
for (j = i + 1; j < length; j++) {
if (a[j] == a[i]) {
a[j] = NULL;
}
}
}
}
}
我真的很困惑这里发生了什么。似乎他们正在释放每个条目并将具有相同内容的条目标记为 NULL。但是,我认为我们不应该重新访问释放的内存?另外,我的方法还能用吗?
【问题讨论】:
-
看起来数组可能有多个条目指向同一个内存。多次释放相同的内存是错误的,因此对于每个条目,您必须检查其他条目是否指向同一块,并将其清除。
-
你的方法根本行不通。它甚至不会尝试处理指向同一位置的多个指针的情况。提供的解决方案具有未定义的行为,但不是因为它正在访问释放的内存。
-
我认为如果我将 a[i] 设置为 NULL,那么每个指向与 a[i] 相同地址的指针也将等于 NULL。这是不正确的吗?
-
@redblacktrees 无效有效。对
free的调用应该发生在 内部循环之后。 -
这是无效的,这也是他们的解决方案具有未定义行为的原因。但是,代码没有访问已释放的内存。只是在
free(x)之后x的值变得不确定,所以你甚至不能检查它。
标签: c free dynamic-memory-allocation