C中的双指针空检查

slwdgvem  于 2023-03-22  发布在  其他
关注(0)|答案(3)|浏览(162)

在C语言中如何检查双指针是否为NULL
我传递了一个双指针how参数的函数。
我需要检查两次,像这样???

typedef struct no_t no_t;

struct no_t
{
    no_t *prev;
    no_t *next;
    void *obj;
};

int32_t dynll_free_node_and_object(no_t **node)
{
    if (node == NULL)
        return -1;
    
    if (*node == NULL)
        return -2; 

    free((*node)->obj);
    (*node)->obj = NULL;
    
    (*node)->prev = NULL;
    (*node)->next = NULL;

    free(*node);  
    *node = NULL;
    
    return 0; 
}
9jyewag0

9jyewag01#

同时检查node*node是可以的,但是该函数可以被记录为只接受非空地址,并且传递空指针的地址可能不是错误。例如,free(NULL)完全可以。
另外请注意,将字段设置为NULL是可选的,因为无论如何都要释放结构内存,并将*node重置为NULL,因此调用代码将不得不取消引用原始指针的副本以尝试读取释放的结构,这无论如何都会有未定义的行为。
以下是一个简化版本:

#include <assert.h>
#include <stdlib.h>

typedef struct no_t {
    no_t *prev;
    no_t *next;
    void *obj;
} no_t;

void dynll_free_node_and_object(no_t **node) {
    assert(node);
    
    if (*node) {
        free((*node)->obj);
        free(*node);
        *node = NULL;
    }
}
jbose2ul

jbose2ul2#

你也可以利用||在可能的情况下会短路它的右手边的事实。也就是说,如果左手边的大小计算为1(或任何非零值),它将不会在它的右手边运行表达式。

if(node == NULL || *node == NULL)
  return -1;

但是,这使得您在失败时使用相同的返回代码。

smdnsysy

smdnsysy3#

if( node == NULL )
    return -1;
    
if( *node == NULL )
    return -2;

如果只检查了*nodenode可能是NULL),或者首先检查了*node(出于上述原因),代码就有调用未定义行为的风险。
如果不同的返回值仅用于噪声,则考虑返回-1\f25 NULL -1:

if (!node || !(*node)) {
    return -1;
}

您可能需要abort()程序:

/* assert() would be disabled in release build. */
abort ();

或者通过允许一个NULL指针来模拟free(NULL),这将是一个NOP。
请注意,将这些指针设置为NULL如下:

(*node)->obj = NULL;
(*node)->prev = NULL;
(*node)->next = NULL;

*node不再指向它的原始位置,所以释放的内存不能通过它访问。(如果调用者保存了原始指针的副本,并试图在它被释放后访问内存,这不是你的问题)。

相关问题