这个变量 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
,我可以看到您犯的一些错误:
- 您可能在完整代码中具有此功能,但不要忘记
#include <stdio.h>
使用printf()
并#include <stdlib.h>
使用malloc()
- 您的函数
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 作为捕获内存问题的工具。