我想知道为什么第一种方法不起作用,但第二种方法不起作用:
//第一种方法
int create_node(struct node *create_me, int init){
create_me = malloc(sizeof(struct node));
if (create_me == 0){
perror("Out of momory in ''create_node'' ");
return -1;
}
(*create_me).x = init;
(*create_me).next = 0;
return 1;
}
int main( void ){
struct node *root;
create_node(root, 0);
print_all_nodes(root);
}
好的,这里的print_all_nodes函数告诉我,root还没有被初始化。现在第二种方法可以正常工作:
struct node* create_node(struct node *create_me, int init){ //<-------
create_me = malloc(sizeof(struct node));
if (create_me == 0){
perror("Out of momory in ''create_node'' ");
exit(EXIT_FAILURE);
}
(*create_me).x = init;
(*create_me).next = 0;
return create_me; //<---------
}
int main( void ){
struct node *root;
root = create_node(root, 0); //<---------------
print_all_nodes(root);
}
在我的理解中(谈论方法1),当我给create_node
函数指向根节点的指针时,它实际上改变了根的x
和next
。
就像你这样做:
void change_i(int* p){
*p = 5;
}
int main( void ){
int i = 2;
printf("%d\n", i);
change_i(&i);
printf("%d", i);
}
实际上它会改变i
。
明白了吗?
有人可以和我分享他/她的知识!
答案 0 :(得分:3)
你需要一个指向指针的指针,而不仅仅是一个指针。
如果要更改另一个函数中的变量,则必须发送指向该变量的指针。如果变量是整数变量,则发送指向该整数变量的指针。如果变量是指针变量,则发送指向该指针变量的指针。
您在问题中说“当我向create_node
函数提供指向根节点的指针时,它实际上会更改根的x
和next
。”你的措辞让我怀疑这里有一些混乱。是的,您要更改x
和next
的内容,而不更改root
的内容。 root
没有x
和next
,因为root
是指向指向包含x
和a的结构的指针next
。您的函数不会更改root
的内容,因为您的函数只获得该指针的副本。
您的代码更改:
int create_node(struct node **create_me, int init) {
*create_me = malloc(sizeof(struct node));
if (*create_me == 0){
perror("Out of momory in ''create_node'' ");
return -1;
}
(*create_me)->x = init;
(*create_me)->next = 0;
return 1;
}
int main( void ){
struct node *root;
create_node(&root, 0);
print_all_nodes(root);
}
答案 1 :(得分:1)
您需要执行{"id":3,"current_money":"333","user_id":1,
"created_at":"\u0622\u0630\u0631 20\u060c 1394",
"updated_at":"\u0622\u0630\u0631 20\u060c 1394",
"currency_id":1,"user":{"id":1,"name":"\u0645\u0647\u062f\u06cc",
"family":"\u067e\u06cc\u0634\u06af\u0648\u06cc","username":"mahdi","token":"",
"email":"pishguy@gmail.com",
"image_file_name":"","mobile_number":"09373036569",
"status":1,"created_at":"\u0622\u0630\u0631 20\u060c 1394",
"updated_at":"\u0622\u0630\u0631 20\u060c 1394"},
"currency_type":null}
之类的操作,然后在被调用的方法中将其作为create_node(&root, 0);
进行访问。 C没有通过参考概念。您需要提供地址以便在另一个函数中访问它。
答案 2 :(得分:1)
这是变量范围的问题。在第一个示例中,您提供了一个指向节点的指针,您可以更改该节点,之后更改将保持不变。但是,您的malloc
更改了此指针,该指针在作用域(您的函数)结束后被丢弃。
在第二个示例中,您返回此指针,因此在被丢弃之前复制它。
这与你给出的例子中的这个相对应。 3:
void change_i(int* p){
*p = 5; // you can 'change i'
p = 5 // but not p (pointer to i), as it is local -> gets discarded after following '}'
}
答案 3 :(得分:1)
当我给create_node函数指向根节点的指针时,它实际上改变了x和下一个root。
你没有给create_node()
函数(在两个版本中)指向根节点的指针,因为你没有根节点,在第一个的地方。
宣言:
struct node *root;
创建root
类型的变量struct node *
并让它未初始化。 root
是一个变量,可以将地址存储在struct node
值的内存中(指向struct node
值的指针)。但代码不会创建任何struct node
值,而root
的值只是垃圾。
接下来,作为调用的结果,函数create_node()
的两个版本都会在参数root
中收到create_me
的垃圾值:
create_node(root, 0);
create_node()
的两个实现的第一件事是忽略它们在create_me
参数中接收的值(无论是否有效),创建类型为struct node
的值并存储其值地址create_me
。
行:
(*create_me).x = init;
(*create_me).next = 0;
将一些值放入新分配的struct node
对象的属性中。
该函数的第一个版本然后返回1并忽略create_me
中存储的值。作为函数参数(函数的局部变量),其值将被丢弃并永久丢失。代码刚刚创建了一个内存泄漏:一块内存已分配但无法访问,因为没有指向它的指针。 不要这样做!
该函数的第二个版本返回create_me
的值(即新分配的类型struct node
的值的地址)。调用代码(root = create_node(root, 0);
)将函数返回的值存储到变量root
中(替换用于初始化此变量的垃圾值)。
非常成功! create_node()
函数的第二个版本创建一个新的struct node
对象,初始化其属性并返回要存储的新对象的地址和/或进一步处理。当不再需要该物体时,不要忘记拨打free(root)
。