指针作为第二个参数而不是返回指针?

Tyl*_*ler 7 c pointers

我注意到在C中接受一个未malloc命中的指针作为第二个参数而不是返回指针是一个常见的习惯用法.例:

/*function prototype*/    
void create_node(node_t* new_node, void* _val, int _type);

/* implementation */
node_t* n;
create_node(n, &someint, INT)
Run Code Online (Sandbox Code Playgroud)

代替

/* function prototype */
node_t* create_node(void* _val, int _type)

/* implementation */
node_t* n = create_node(&someint, INT)
Run Code Online (Sandbox Code Playgroud)

两种方法的优点和/或缺点是什么?

谢谢!

编辑谢谢大家的回答.我现在非常清楚选择1的动机(我应该指出,选择1的指针参数应该与我最初想的相反).

Ale*_*lli 16

接受一个指针(调用者负责malloc'ing或不负责)要填写的内存,在返回指针(必然是malloc'ed)的灵活性方面提供了明显的优势.特别是,如果调用者知道它需要使用仅在某个函数内返回的任何东西,它可以传入堆栈分配的结构或数组的地址; 如果它知道它不需要重入,它可以传入一个static结构或数组的地址- 在任何一种情况下,一个malloc/free对都会被保存,这样的节省就会增加! - )


Sam*_*war 6

这没有多大意义.C中的指针按值传递,就像其他对象一样 - 差别在于值.使用指针,值是内存地址,传递给函数.但是,你仍然在复制值,所以当你malloc,你将改变函数内部指针的值,而不是外部的指针值.

void create_node(node_t* new_node, void* _val, int _type) {
    new_node = malloc(sizeof(node_t) * SIZE);
    // `new_node` points to the new location, but `n` doesn't.
    ...
}

int main() {
    ...
    node_t* n = NULL;
    create_node(n, &someint, INT);
    // `n` is still NULL
    ...
}
Run Code Online (Sandbox Code Playgroud)

有三种方法可以避免这种情况.首先,正如您所提到的,从函数返回新指针.第二种是获取指针指针,从而通过引用传递它:

void create_node(node_t** new_node, void* _val, int _type) {
    *new_node = malloc(sizeof(node_t) * SIZE);
    // `*new_node` points to the new location, as does `n`.
    ...
}

int main() {
    ...
    node_t* n = NULL;
    create_node(&n, &someint, INT);
    // `n` points to the new location
    ...
}
Run Code Online (Sandbox Code Playgroud)

第三个是简单地malloc n在函数调用之外:

int main() {
    ...
    node_t* n = malloc(sizeof(node_t) * SIZE);
    create_node(n, &someint, INT);
    ...
}
Run Code Online (Sandbox Code Playgroud)