【问题标题】:Should you free pointers that reference already allocated data?您是否应该释放引用已分配数据的指针?
【发布时间】:2021-09-13 18:05:52
【问题描述】:

我知道指向malloc-ed 数据的指针需要在适当的地方释放。 例如:

Item* items = (Item*)malloc(sizeof(Item) * 1);

^ 完成后,我必须释放它。有道理。

但是,请考虑以下结构:

typedef struct Items {
    Vector* fruits;
} Items;

Vector 在哪里:

typedef struct Vector {
    void** data;
    int size;
 } Vector;

假设我已经为Items 结构分配了内存,并且Vector 成员包含例如3 个项目(另一个结构Boxes)。

如果我有一个 Boxes 指针变量引用 Items 结构中 Vector 的 第二个成员,使用后是否需要释放它?

// Does `box1` need to be explicitly freed?
Boxes* box1 = items->fruits[1]; // `items` is of type `Items`

我了解该变量 box1 没有显式堆分配。 只有堆分配的指针需要被释放吗?

【问题讨论】:

  • 你没有释放指针,你释放了分配
  • 没有。你需要释放你分配的东西(例如盒子数组),尝试释放一个盒子是不正确的。
  • 如果这个问题是关于 C++ 的,那么答案就是 RAII。如果这个问题是关于 C 的,那么删除 C++ 标签
  • 只发布你拥有的东西。如果您不知道它来自哪里,或者它是如何分配的,请不要用它
  • 鉴于 malloctypedef struct 和(在较小程度上)void*,我将假设这是 C 代码和 C++ 答案,例如“不要使用原始指针”请勿应用。删除 [c++] 标签。

标签: c pointers


【解决方案1】:

男人 malloc/free

malloc() 函数分配 size 字节并返回一个指向已分配内存的指针。 ...

free() 函数释放 ptr 指向的内存空间,该内存空间肯定是之前调用 malloc() 时返回的,...

  • 话虽如此,malloc 返回的地址必须稍后传递给free,两者之间没有任何关系。

  • 每个malloc 后面必须跟一个对应的free

【讨论】:

    【解决方案2】:

    如果你执行这个:

    Boxes* box1 = items->fruits[1];
    

    那么box1items->fruits[1]是同一个指针;它们指的是同一个对象,在内存中只有一个地址。

    如果您调用free(items->fruits[1]),则items->fruits[1] 将变为无效指针。因为box1是同一个指针,所以也失效了。

    如果您知道 items->fruits[1] 的内存管理在其他地方进行了处理,并且您只希望在某个代码块中为其取一个较短的名称,那么通常可以安全地为对象创建一个别名,例如 @987654328 @。

    您必须绝对确保在程序中box1 仍在词法范围内的某个时刻不要继续使用box1(因此访问变量本身是 hunky dory),但是已经执行了一些代码,它已经破坏了items->fruits[1],以至于box1 已经隐形地、悄悄地变得无效。

    如果您有一些具有box1 别名的代码,并且它调用的某些函数可能会破坏items->fruits[1] 并用新的指针替换该指针。在这种情况下,您可以选择新值:

    Boxes *box1 = items->fruits[1];
    
    maybe_replaces_items(items); // items->fruits[1] potentially overwritten
    
    box1 = items->fruits[1]; // pick up latest fruits[1]
    

    这种东西是bug的来源。

    您知道“计算机科学中只有两个难点:缓存失效和命名”的计算谚语吗?嗯,这是缓存失效:box1 是某个指针的缓存副本,它可能已经失效,必须刷新。

    【讨论】:

      猜你喜欢
      • 2019-03-20
      • 1970-01-01
      • 1970-01-01
      • 2011-11-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-29
      • 2023-03-11
      相关资源
      最近更新 更多