【问题标题】:Possible to check if a pointer is freed/invalid?可以检查指针是否被释放/无效?
【发布时间】:2021-04-15 05:03:50
【问题描述】:

我认为对此的简短回答是“否”,但假设我有以下功能:

void print_table(const hash_table *table)
{

    printf("-------------------------- SIZE: %zu / %zu -----------------------\n", table->count, table->size);
    for (int i=0; i < table->size; i++) {
        hash_item *item = table->items[i];
        if (item != NULL && item != &HT_DELETED_ITEM)
            printf("Idx: %d {%s: %s}\n", i, item->key, item->value);

    }
}

当然,如果table 已被释放,这将是seg fault。我认为“捕捉”就像在顶部进行空检查一样简单:

// this top part see
if (table == NULL) {
    printf("[Empty]");
    return;
}

当然,在 C 中没有什么是那么简单的。有没有办法在 C 中进行类似的检查,或者甚至可能是一种 hack-ish 方式来存储结构中的布尔值之类的东西,说明它是否已被“释放” ' 还是不?

作为我现在得到的一个例子:

// first time running in with a valid `table` object
-------------------------- SIZE: 2 / 64 -----------------------
Idx: 10 {Mark: Jones}
Idx: 40 {Ben: Johnson}

// second time after free'd
Segmentation fault: 11 <-- I know this, but any way to short-circuit this?

【问题讨论】:

  • 使用 c++ 和 unique_ptr ?
  • @OznOg 我不会 C++
  • 我想说,只要确保您的指针在不使用时为NULL。当你初始化它时,除非你立即给它分配一个地址,否则让它指向NULL。释放后,立即使其指向NULL。每当您需要检查它是否指向某个东西时,您可以查看它是否指向NULL
  • @mediocrevegetable1 我明白了,这是否意味着在“删除”函数中我需要将指针传递给指针结构,而不仅仅是指针结构本身?
  • @carl.hiass 是的,我认为这将是一个好主意,这样您就可以修改指针以指向 NULL。一个例子是void hash_table_delete(hash_table** table_ptr) {free(*hash_table_ptr); *hash_table_ptr = NULL;} 根据man page on free,如果指针是NULLfree 不会做任何事情:"如果 ptr 为 NULL,则不执行任何操作。" 因此,您甚至不必对NULL 进行任何检查,free 会为您完成。当然如果*has_table_ptr是一个无效的地址,会有UB但那是调用者的错

标签: c memory-management


【解决方案1】:

这应该通过记录在案的先决条件来处理。如果您编写一个函数,它应该记录调用该函数所需的先决条件,然后调用代码负责确保满足先决条件。这应该是一个先决条件。

例如,调用free 的前提条件是传入的指针指向malloc(或相关函数)分配的内存并且尚未释放。 free 函数不会尝试检查是否满足此前提条件,因为这是调用代码的责任。

不要依赖指针值为NULL。这不是一个好习惯,当你继续学习更复杂的编程技能时,它会对你不利。虽然使用NULL 的指针值来指示对象尚未分配或已被释放当然是有意义的,但它应该绝不不加思索地使用并且只 用于特别有意义的地方。

主要原因很简单——有时会有两个指针指向同一个对象。当您调用 free 时,您通常无法将 both 设置为 NULL。如果您习惯于假设指针始终为NULL(如果它没有指向分配的内容),那么您将难以处理这样的代码。

【讨论】:

    猜你喜欢
    • 2011-06-02
    • 2023-03-11
    • 1970-01-01
    • 1970-01-01
    • 2012-01-08
    • 2011-11-16
    • 2021-10-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多