C:处理指针的方法

时间:2015-12-11 11:53:21

标签: c

我想知道为什么第一种方法不起作用,但第二种方法不起作用:

//第一种方法

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函数指向根节点的指针时,它实际上改变了根的xnext

就像你这样做:

void change_i(int* p){
    *p = 5;
}
int main( void ){

    int i = 2;
    printf("%d\n", i);
    change_i(&i);
    printf("%d", i);


}

实际上它会改变i。 明白了吗? 有人可以和我分享他/她的知识!

4 个答案:

答案 0 :(得分:3)

你需要一个指向指针的指针,而不仅仅是一个指针。

如果要更改另一个函数中的变量,则必须发送指向该变量的指针。如果变量是整数变量,则发送指向该整数变量的指针。如果变量是指针变量,则发送指向该指针变量的指针。

您在问题中说“当我向create_node函数提供指向根节点的指针时,它实际上会更改根的xnext。”你的措辞让我怀疑这里有一些混乱。是的,您要更改xnext的内容,而不更改root的内容。 root没有xnext,因为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)