C:从函数外部访问指针
我有以下代码:
int takeEven(int *nums, int numelements, int *newlist) {
newlist = malloc(numelements * sizeof *newlist);
int i, found = 0;
for(i = 0; i < numelements; ++i, nums++) {
if (!(*nums % 2)) {
*(newlist++) = *nums;
found++;
}
}
newlist -= found;
printf("First number found %d\n", *newlist); // <= works correctly
return found;
}
int main()
{
int nums[] = {1,2,3,4,5};
int *evenNums;
int i;
int n = takeEven(nums, sizeof(nums) / sizeof(*nums), evenNums);
for (i = 0; i < n; ++i) {
printf("%d\n", *(evenNums++));
}
return 0;
}
上述代码的输出:
-1
2088999640
2088857728
如果我在返回函数之前尝试打印 newlist
指针的第一个元素 (printf("First number found %d\n" ,*newlist);
),它按预期工作,但是为什么当我尝试从函数外部访问指针时,我从看似未分配的地址获取这些值?
I have the following code:
int takeEven(int *nums, int numelements, int *newlist) {
newlist = malloc(numelements * sizeof *newlist);
int i, found = 0;
for(i = 0; i < numelements; ++i, nums++) {
if (!(*nums % 2)) {
*(newlist++) = *nums;
found++;
}
}
newlist -= found;
printf("First number found %d\n", *newlist); // <= works correctly
return found;
}
int main()
{
int nums[] = {1,2,3,4,5};
int *evenNums;
int i;
int n = takeEven(nums, sizeof(nums) / sizeof(*nums), evenNums);
for (i = 0; i < n; ++i) {
printf("%d\n", *(evenNums++));
}
return 0;
}
The output of the above code:
-1
2088999640
2088857728
If I try printing the first element of the newlist
pointer before returning the function (printf("First number found %d\n", *newlist);
), it works as intended, but why is it that when I try to access the pointer from outside of the function I get those values from seemingly unmalloced addresses?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
您正在按值传递 newList 指针,因此它不会被您的函数修改。你应该这样做。
You are passing the newList pointer by value, so it will not be modified by your function. You should do instead.
您需要传入一个指向指针的指针,即
int **newlist
。具体来说,newlist 是按值传递到函数中的,因此 main 中的 newlist 和函数内部的 newlist 是两个完全不同的变量。您对偶数的测试也存在一个错误:
您还可以看看这个问题< /a> 来自 C-FAQ,它也处理您的问题:
问:我有一个接受并应该初始化指针的函数:
但是当我这样调用它时:
调用者中的指针保持不变。
答:您确定该函数初始化了您所认为的内容吗?请记住,C 中的参数是按值传递的。在上面的代码中,被调用的函数仅更改传递的指针副本。为了使其按您的预期工作,一个修复方法是传递指针的地址(该函数最终接受指向指针的指针;在这种情况下,我们本质上是模拟按引用传递):
另一种解决方案是让函数返回指针:
另请参阅问题 4.9 和 4.11。
You need to pass in a pointer to pointer, i.e.
int **newlist
. Specifically, newlist is being passed into your function by value, so the newlist inmain
and inside your function are two completely different variables.There is also a bug in your test for even numbers:
You can also take a look at this question from the C-FAQ which deals with your problem also:
Q: I have a function which accepts, and is supposed to initialize, a pointer:
But when I call it like this:
the pointer in the caller remains unchanged.
A: Are you sure the function initialized what you thought it did? Remember that arguments in C are passed by value. In the code above, the called function alters only the passed copy of the pointer. To make it work as you expect, one fix is to pass the address of the pointer (the function ends up accepting a pointer-to-a-pointer; in this case, we're essentially simulating pass by reference):
Another solution is to have the function return the pointer:
See also questions 4.9 and 4.11.
函数末尾的新列表与调用函数时的新列表不同。
您正在传递指针的副本,然后 malloc 更改该指针(函数内部的)以指向分配的内存,但外部指针仍然未修改。
您需要使用指向指针的指针作为参数,以便您可以通过双重间接设置来设置 ourtside 指向的位置。
因此,您实际上是为函数提供了存储所需地址的位置,并要求函数在那里存储有效的内存指针。
The newlist you have at the end of the function is not the same as you have when calling the function.
You are passing a copy of a pointer, then malloc changes that pointer(internal to the function) to point to allocated memory, but the outside one is still unmodified.
You need to use a pointer to pointer as a parameter so that you can set where the ourtside one points by double indirection.
So effectively you are giving the function the place where you store the address of what you want and asking the function to store there a valid memory pointer.
您在这里按值传递指针:
这意味着在该函数内创建了指针的副本。然后,您覆盖该副本:
由于它只是一个副本,因此调用者将看不到您的分配结果。您在这里似乎想要的是通过引用传递指针 - 为此,您需要一个指向指针的指针:
并且不要忘记
free
:You're passing a pointer by value here:
Which means that a copy of the pointer is made within that function. You then overwrite that copy:
Since it is but a copy, the caller won't see the result of your assignment. What you seemingly want here is to pass a pointer by reference - for that, you need a pointer to pointer:
And don't forget to
free
:在 C 中,一切都是按值传递的。因此,您将
evenNums
的副本传递给该函数。无论您在函数内部对其进行什么修改,都不会反映在外部。您需要将int**
作为第三个参数。In C, everything is passed by value. So you are passing a copy of
evenNums
to the function. Whatever you modify it inside the function doesn't get reflected outside. You need toint**
as the third parameter.