c语言 - 在函数中传递空指针



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

int main(void) {
int * num_results = NULL;
int num = 4;
set(num_results, num);
printf(“%dn”, *num_results);
return 0;
}
void set(int * results,num){
num_results = malloc(sizeof(int));
*num_results = num;
}

我将猜测您对问题的真正含义,并尝试给出一个体面的答案。

我猜您想通过将num_results作为指针传递给函数set来将其更改为等于num,我可以看到您犯的一些错误:

  1. 您可能在完整代码中具有此功能,但不要忘记#include <stdio.h>使用printf()#include <stdlib.h>使用malloc()
  2. 您的函数set()应该在main()之前声明,您可以通过在main()之前声明原型或简单地在main()之前定义set()函数来做到这一点。

现在让我们转到您的解决方案:您希望将num_results作为参数传递给函数,分配一些内存并将地址分配给num_results然后将值更新为num中的值。

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

由于您要分配内存并将其地址分配给num_results,因此您必须传递指向指针的指针,因此您传递的是保存int*变量的位置以及实际可以更改它的地址。

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

您还必须更改函数的主体,因为您现在使用的是int **,您希望将新地址分配给*results,因为results == &num_results,并将 num 分配给**results,因为*results = num_results

我希望我的解释不是很混乱,希望有人可以用另一个答案或编辑我的答案来更好地解释它。最终代码:

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

这里 NULL 在set()中传递给results变量,当您将内存分配给results时,NULL 被有效的内存地址替换,但您需要了解它只会保存在变量results因为它是要set()的局部变量

您应该将num_results的地址传递给set(),以便将set()中分配的内存保留在main()中,或者只是在 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("%dn", *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("%dn", *num_results);
return 0;
}
void set(int **results,int num){
*results = malloc(sizeof(int));
*(*results) = num;
}

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

这似乎是个错误的问题,因为您的set()函数似乎旨在将num的值复制到其他地方,而不是更新num本身。

你的问题之一是在哪里复制它。 目前,您为此动态分配一些内存,并将其复制到那里。 就目前而言,这很好,但是指向已分配内存的指针不会传达回调用方。 这是因为所有 C 函数都按值传递参数,特别是,您的main()传递按值set()的第一个参数(类型int *的值)。 修改函数的副本不会影响其调用者的副本 - 这就是按值传递的全部内容。

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

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

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

在帮助程序函数中,您应该引用第一个参数名称结果而不是num_results。您的帮助程序函数应如下所示:

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

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

#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("%dn", *num_results);
return 0;
}

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

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

相关内容

  • 没有找到相关文章

最新更新