在函数中传递空指针

时间:2017-09-06 03:46:28

标签: c pointers null

这个变量num保持为0.我怀疑这是因为我传入一个NULL指针,但是我被限制为main(和参数)。如何调整辅助函数的内容以正确更新num?

int main(void) {
    int * num_results = NULL;
    int num = 4;
    set(num_results, num);
    printf(“%d\n”, *num_results);
    return 0;
}

void set(int * results,num){
    num_results = malloc(sizeof(int));
    *num_results = num;
}

5 个答案:

答案 0 :(得分:2)

我会猜测你对你的问题的真正含义,并尝试给出一个不错的答案。

我想你想将num_results更改为等于num,将其作为指针传递给函数set,我可以看到你犯了一些错误:

  1. 您可能已在完整代码中使用此代码,但不要忘记#include <stdio.h>使用printf()#include <stdlib.h>使用malloc()
  2. 您的函数set()应在main()之前声明,您可以在main()之前声明prototype或在set()之前定义main()函数来执行此操作{1}}。
  3. 现在让我们转到您的解决方案:您希望将num_results作为参数传递给函数,分配一些内存并将地址分配给num_results,然后将值更新为num中的值{1}}。

    当您传递int *作为参数时,我猜您已经知道通过传递int,您只需提供int变量内部内容的副本。这与int *的工作方式相同,您没有传递对num_results的引用,以便您可以更新指针的地址,而您正在传递副本当前地址NULL,不会被修改。 可以被修改的是当前地址内部的内容,但当前地址是NULL,因此无法真正修改。

    由于您要分配内存并将其地址分配给num_results,因此您必须将指针传递给指针,因此您要传递int*所在的地址变量被保留,你可以实际改变它。

    这样,您的函数应该看起来像void set(int ** results, int num),您应该使用set(&num_results, num)调用它,因此您将传递对num_results的引用,您可以在其中更改它指向的地址,当前{{ 1}}然后NULL返回的地址。

    您还必须更改功能的正文,因为您现在使用的是malloc(),您希望将新地址分配给int **,因为*results,并将num分配给results == &num_results,因为**results

    我希望我的解释不会让人感到困惑,希望有人可以通过另一个答案或编辑我的方式更好地解释它。最终代码:

    *results = num_results

答案 1 :(得分:1)

set(num_results, num);

这里将NULL传递给results中的set()变量,当你将内存分配给results时,NULL被有效的内存地址替换,但是你需要理解它将是仅在results变量中保存为set()

的局部变量

您应该将num_results的地址传递给set(),以便set()中分配的内存保留在main()中,或者只将内存分配给num_results主函数然后将其传递给set(),如下所示:

#include <stdio.h>
int main() {
    int *num_results = NULL;
    int num = 4;
    num_results = malloc(sizeof(int));
    set(num_results, num);
    printf("%d\n", *num_results);
    return 0;
}

void set(int *results,int num){
    *results = num;
}

另一个例子是:

#include <stdio.h>
#include <stdlib.h>
void set(int **r, int num);
int main() {
    int *num_results = NULL;
    int num = 4;
    /*num_results = malloc(sizeof(int));*/
    set(&num_results, num);
    printf("%d\n", *num_results);
    return 0;
}

void set(int **results,int num){
    *results = malloc(sizeof(int));
    *(*results) = num;
}

答案 2 :(得分:1)

  

如何调整辅助函数的内容以正确更新num?

这似乎是错误的问题,因为您的set()函数似乎打算将num的值复制到其他位置,而不是更新num本身。

您的一个问题是其中要复制它。目前,您为此动态分配一些内存,并将其复制到那里。尽管它很好,但指向分配的内存的指针不会传回给调用者。这是因为所有C函数都通过值传递参数,特别是,main()按值传递set()的第一个参数(类型为int *的值) )。修改功能的副本不会影响其来电者的副本 - 这就是传递值的全部内容。

您可能忽略了一个简单的事实:动态分配不是获取有效指针值的唯一方法,甚至也不是最重要或最常见的指针值。当您看到指针时,您不应自动寻找malloc()。您可以非常轻松地从数组中获取指针,但更重要的是,您可以通过应用地址运算符(&)来获取指针值。

为了使set()函数能够在不诉诸全局变量或更改其签名的情况下执行其调用者可以看到的工作,调用者必须将第一个参数传递给调用者可以访问的对象的有效指针,例如作为自己的局部变量之一。指针按值传递,因此函数获取副本,但它是副本:它指向调用者指针所执行的同一对象。因此set()函数可以通过指向它的指针副本来修改指向对象。

假设您的main()声明了自己的局部变量resultint。你认为它可以用&result做什么?

答案 3 :(得分:0)

您的代码无法编译。编译器错误消息将告诉您如何解决它们。这是一个固定的。

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

int * num_results = NULL;

void set(int * results, int num){
    num_results = malloc(sizeof(int));
    *num_results = num;
}

int main(void) {
    int num = 4;
    set(num_results, num);
    printf("%d\n", *num_results);
    return 0;
}

为了学习它,您可以在此处查看编译错误消息并尝试自行修复:https://segfault.stensal.com/a/XWfv8rxCJHVtAuRQ

免责声明:我建立了stensal.io作为捕捉内存问题的工具。

答案 4 :(得分:0)

在辅助函数中,您应该引用第一个参数名称结果而不是num_results。你的帮助函数应该是:

void set(int * results, int num){
    results = malloc(sizeof(int));
    *results = num;
}