这在某种程度上是一个主观问题,但似乎应该有一个标准.我正在制作树状数据结构,我想知道从函数传递新节点的最佳方法.我有几个想法,但我不知道哪个是最安全/最有效的.
这是我的代码的简化:
typedef struct Node {
struct Node *left;
struct Node *right;
int value;
} Node;
int f() {
//do stuff
}
Node *new_node() {
Node n = {NULL, NULL, f()};
return &n;
}
int main() {
Node a = {new_node(), new_node(), 0};
}
Run Code Online (Sandbox Code Playgroud)
显然,这不起作用,因为new_node()
函数返回的指针指向堆栈分配的数据,一旦new_node()
结束就会释放.但是解决这个问题的最佳方法是什么?
一种可能性是n
在堆上分配,如下所示:
Node *new_node() {
Node *n = (Node *) malloc(sizeof(Node)); //unsure if the cast is necessary here, but that's not relevant
n->left = NULL;
n->right = NULL;
n->value = f();
return n;
}
Run Code Online (Sandbox Code Playgroud)
但这感觉不对,因为它要求调用者函数直接处理内存清除,这可能会很快变得混乱.
我见过的另一个选项(特别是当对象是数组或缓冲区而不是对象时)是传递指向函数的指针,只是修改指针的内容.
void new_node(Node *n) {
n->left = NULL;
n->right = NULL;
n->value = f();
}
int main() {
Node n = {NULL, NULL, 0};
Node n1 = n;
new_node(&n);
new_node(&n1);
Node a = {&n, &n1, 0};
}
Run Code Online (Sandbox Code Playgroud)
或者你可以直接传递数据,特别是因为Node
在这种情况下这么小:
Node new_node() {
Node n = {NULL, NULL, f()}
return n;
}
Run Code Online (Sandbox Code Playgroud)
这似乎会慢一点,虽然我不确定.
关于这个主题已经有了一些答案,但它们都是用C++编写的,并且处理引用和指针,我恐怕我并不真正理解它们之间的区别.
这样做的标准方法是什么?
(对不起,如果这太长了)
您涵盖了所有四种可用方法,包括一种无效方法.在他们之间挑选取决于您的设计偏好: