我不太了解传递给函数*mode1**mode2的区别。

我写了一些例子。 (注意:type可以是任何类型)

[代码1]

#include <stdio.h>

void function (type *vet)
{
    /* other */
}

int main ()
{
    type *vet;

    function (vet)

    /* other */

    return 0;
}

[代码2]
#include <stdio.h>

void function (type **vet)
{
    /* other */
}

int main ()
{
    type *vet;

    function (&vet)

    /* other */

    return 0;
}

我知道:第一种情况是指针,第二种情况是指向指针的指针。但是为什么例如在第二种情况下,如果我通过&vet可以在function()中分配内存并在main()中释放它,而在第一种情况下则不可以呢?

我搜寻可以很好地解释我之间差异的人。在这两种情况下我该怎么办?如何以及在哪里分配或重新分配?而且免费吗?并在功能上修改兽医?

最佳答案

原始问题

主要(最重要的)区别是调用函数中的值是否可以更改。

  • 在第一个示例中,被调用函数在调用代码中获取指针的副本,并且无法修改调用代码中的指针。
  • 在第二个示例中,被调用函数获得指向该指针的指针,并且通过在被调用函数中分配给*vet,可以修改被调用函数中的值。



  • 在第二种情况下,function()中的代码可以修改main()中的实际指针,因此vetmain()的值以分配的指针值结束,因此可以释放该指针值。在第一种情况下,main()中的值未被调用的函数修改,因此main()无法释放数据。



    在第一种情况下,您可以在函数中使用malloc()realloc(),但也应在返回之前释放分配的内存,除非您的代码将值存储在全局变量中(在这种情况下,您可以委托(delegate)其他代码来处理free()) ,但最好弄清楚是哪个代码负责,在任何情况下使用全局变量可能都不是一个好主意)。或者除非您更改函数签名并返回指向分配数据的指针,否则调用代码应释放该指针。

    在第二种情况下,您可以在被调用函数中分配或重新分配内存,并将其分配给其他函数使用,并由调用函数释放。



    在这两个函数中,您都可以根据需要修改本地vet变量。任何函数的任何参数都是如此。您不一定要做的就是在调用函数中修改值;为此,您必须在调用函数中有一个指向值的指针。在第一个函数中,您无法在vet中更改main()的值;在第二个中,您可以。在这两个函数中,您都可以更改vet指向的内容。 (一个小问题是在三种上下文中混合了vetmain()这两个不同的功能。这两个函数中的vet这个名称指向了不同类型的事物。)

    扩展问题


    #include <stdio.h>
    #define NUM (10)
    
    struct example
    {
        /* ... */
    }
    
    void dealloc (struct example *pointer)
    {
        free (pointer);
    }
    
    int main()
    {
        struct example *e;
        e = malloc (NUM * sizeof(struct example));
        if (e == NULL)
            return -1;
        struct example *e_copy = e;
        dealloc (e_copy);
        return 0;
    }
    

    此代码是合法的。您将指针的值(的副本)传递给dealloc()函数;它将指针传递给free(),释放释放的内存。返回dealloc()后,ee_copy中的指针值与以前相同,但是它们不再指向已分配的内存,并且对该值的任何使用都会导致 undefined 的行为。可以为他们分配一个新值。旧值不能可靠地取消引用。


    #include <stdio.h>
    #define NUM (10)
    
    struct example
    {
        /* ... */
    }
    
    int main()
    {
        struct example *e;
        e = malloc (NUM * sizeof(struct example));
        if (e == NULL)
            return -1;
        struct example *e_copy = e;
        free (e_copy);
        return 0;
    }
    

    此示例与上一个示例的区别在于,您可以直接在free()中调用main(),而不是从函数dealloc()中调用。

    会有所作为的是:
    void dealloc(struct example **eptr)
    {
        free(*eptr);
        *eptr = 0;
    }
    
    int main()
    {
        ...
        dealloc(&e_copy);
        return 0;
    }
    

    在这种情况下,dealloc()返回后,e_copy是空指针。您可以再次将其传递给free(),因为释放空指针是无操作的。两次释放非null指针是 undefined 的行为-通常会导致问题,应不惜一切代价避免。请注意,即使现​​在,e包含最初由malloc()返回的指针;但是使用该指针值会再次导致 undefined 的行为(但是设置e = 0;e = NULL;e = e_copy;很好,并且使用e = malloc(sizeof(struct example));或类似方法也可以。

    关于c - 传递参数(如* mode1或** mode2)之间的区别,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/21175693/

    10-11 21:57