为啥在这种情况下我必须将指针传递给指针

Posted

技术标签:

【中文标题】为啥在这种情况下我必须将指针传递给指针【英文标题】:Why do I have to pass a pointer to a pointer in this case为什么在这种情况下我必须将指针传递给指针 【发布时间】:2016-06-02 15:34:27 【问题描述】:

这个问题建立在我的previous question 之上。

我有这个结构。它使用 SDL2:

void init_window(SDL_Window *window)

    window = SDL_CreateWindow(…);


int main(void)
 
    SDL_Window  *window;
    init_window(window);

这不起作用。建议的答案是,我使用*&window 作为函数参数,效果很好。 我将*&window 改写为**window 如下:

void init_window(SDL_Window **window)

    *window = SDL_CreateWindow(…);


int main(void)
 
    SDL_Window  *window;
    init_window(&window);

而且它也有效。但我仍然不明白为什么第一个版本不起作用。我查找了implementation details of SDL_Window,它只是一个普通的typedef 结构,可以将其放入普通的命名空间中。 SDL_CreateWindow 返回SDL_Surface *

为了描绘我的困境,我编写了这个简单的程序:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct Person

    char *name;
    int age;
 Person;

Person *person_create(char *name, int age)

    Person *who = malloc(sizeof(Person));
    who->name   = strdup(name);
    who->age    = age;

    return who;


void person_get_old(Person *who)

    who->age += 30;


int main(void)

    Person *susan = person_create("Susan", 23);
    person_get_old(susan);
    printf("%i\n", susan->age);

这会像预期的那样打印53,而我不必使用指向指针语义的指针。 我的实现与 SDL2 的实现有什么区别。这不是 SDL2 问题,因为回答我上一个问题的人可以在不了解 SDL2 的情况下回答这个问题,所以我似乎遗漏了一些实现细节。希望有人能赐教。

【问题讨论】:

选择一个语言标签,C和C++是不同的。 (你的最后一个程序在 C++ 中无效) auto init_window(SDL_Window **window) 在 C++(在 C++17 之前!)和 C 中是非法的。你的编译器应该对此发表评论。也许您打算返回 void ;或按照您在测试程序中使用的模型并拥有SDL_Window *init_window(void) 我可以看到前两个如何在 C 中无效(auto 返回类型在 C 中不存在)以及第三个如何在 C++ 中无效(malloc),但我想知道为什么前两个在 C++ 中也应该是无效的? auto 直到 C++17 才添加免费函数的返回类型推导 【参考方案1】:

这里有一个更简单的例子来说明:

void foo(int p) //create new copy of int

    p = 0; //modify copy, original is unchanged

void bar(int* p) //create new copy of pointer

    *p = 0; //modify object pointer is set to

在您的 SDL 示例中,您尝试执行 foo。目标是将指针设置为新值。但是,您只复制了指针,所有更改都对副本进行了。

在您的Person 示例中,您正在执行bar。你有一个被指向的对象,你想修改它。正确的做法是通过指针(或引用)传递它。

既然你有一个想要修改的对象,你需要通过指针(或引用)来传递它。由于该对象本身就是一个指针,因此它将是一个指向指针的指针。

【讨论】:

【参考方案2】:

您的实现与 SDL2 的区别在于,您的实现返回一个指针,而调用代码将其分配给一个变量。

在 SDL2 实现中,被调用函数想要存储指针,而您希望它存储在调用代码定义的现有指针中。它需要知道指针的存储位置,因此它需要一个指向指针的指针

【讨论】:

以上是关于为啥在这种情况下我必须将指针传递给指针的主要内容,如果未能解决你的问题,请参考以下文章

为啥我不能将模板函数指针传递给可变参数函数?

为啥传递给函数的指针的值没有改变? [复制]

Java - 将指向对象的指针传递给函数

传递函数指针

C语言基础:指针相关概念(指针的算术运算 指针数组指向指针的指针 传递指针给函数 从函数返回指针 )为啥C 语言不支持在调用函数时返回局部变量的地址?

为啥指针不能传递正确的值(C)?