C:从函数外部访问指针

发布于 2024-08-12 01:48:43 字数 905 浏览 5 评论 0原文

我有以下代码:

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

慈悲佛祖 2024-08-19 01:48:43

您正在按值传递 newList 指针,因此它不会被您的函数修改。你应该这样做。

int takeEven(int *nums, int numelements, int **newlist) {
    *newlist = malloc(numelements * sizeof *newlist);
    ...
}

...

int n = takeEven(nums, sizeof(nums) / sizeof(*nums), &evenNums);

You are passing the newList pointer by value, so it will not be modified by your function. You should do instead.

int takeEven(int *nums, int numelements, int **newlist) {
    *newlist = malloc(numelements * sizeof *newlist);
    ...
}

...

int n = takeEven(nums, sizeof(nums) / sizeof(*nums), &evenNums);
橙幽之幻 2024-08-19 01:48:43

您需要传入一个指向指针的指针,即int **newlist。具体来说,newlist 是按值传递到函数中的,因此 main 中的 newlist 和函数内部的 newlist 是两个完全不同的变量。

您对偶数的测试也存在一个错误:

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

int takeEven(int *nums, int numelements, int **newlist) {
    int *list = malloc(numelements * sizeof **newlist);
    *newlist = list;  // this modifies the value of newlist in main
    int i, found = 0;
    for(i = 0; i < numelements; ++i, nums++) {
        if ((*nums % 2) == 0) {
            *(list++) = *nums;
            found++;
        }
    }
    list -= found;
    printf("First number found %d\n", *list); // <= 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;
}

您还可以看看这个问题< /a> 来自 C-FAQ,它也处理您的问题:

问:我有一个接受并应该初始化指针的函数:

void f(int *ip)
{
    static int dummy = 5;
    ip = &dummy;
}

但是当我这样调用它时:

int *ip;
f(ip);

调用者中的指针保持不变。

答:您确定该函数初始化了您所认为的内容吗?请记住,C 中的参数是按值传递的。在上面的代码中,被调用的函数仅更改传递的指针副本。为了使其按您的预期工作,一个修复方法是传递指针的地址(该函数最终接受指向指针的指针;在这种情况下,我们本质上是模拟按引用传递):

void f(ipp)
int **ipp;
{
    static int dummy = 5;
    *ipp = &dummy;
}

...

int *ip;
f(&ip);

另一种解决方案是让函数返回指针:

int *f()
{
    static int dummy = 5;
    return &dummy;
}

...

int *ip = f();

另请参阅问题 4.94.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 in main and inside your function are two completely different variables.

There is also a bug in your test for even numbers:

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

int takeEven(int *nums, int numelements, int **newlist) {
    int *list = malloc(numelements * sizeof **newlist);
    *newlist = list;  // this modifies the value of newlist in main
    int i, found = 0;
    for(i = 0; i < numelements; ++i, nums++) {
        if ((*nums % 2) == 0) {
            *(list++) = *nums;
            found++;
        }
    }
    list -= found;
    printf("First number found %d\n", *list); // <= 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;
}

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:

void f(int *ip)
{
    static int dummy = 5;
    ip = &dummy;
}

But when I call it like this:

int *ip;
f(ip);

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):

void f(ipp)
int **ipp;
{
    static int dummy = 5;
    *ipp = &dummy;
}

...

int *ip;
f(&ip);

Another solution is to have the function return the pointer:

int *f()
{
    static int dummy = 5;
    return &dummy;
}

...

int *ip = f();

See also questions 4.9 and 4.11.

鱼忆七猫命九 2024-08-19 01:48:43

函数末尾的新列表与调用函数时的新列表不同。

您正在传递指针的副本,然后 malloc 更改该指针(函数内部的)以指向分配的内存,但外部指针仍然未修改。

您需要使用指向指针的指针作为参数,以便您可以通过双重间接设置来设置 ourtside 指向的位置。

int use_pointed_memory(char **pointer){
  *pointer = malloc();
}

char *myptr;
use_pointed_memory(&myptr);

因此,您实际上是为函数提供了存储所需地址的位置,并要求函数在那里存储有效的内存指针。

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.

int use_pointed_memory(char **pointer){
  *pointer = malloc();
}

char *myptr;
use_pointed_memory(&myptr);

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.

梨涡 2024-08-19 01:48:43

您在这里按值传递指针:

int n = takeEven(nums, sizeof(nums) / sizeof(*nums), evenNums);

这意味着在该函数内创建了指针的副本。然后,您覆盖该副本:

newlist = malloc(numelements * sizeof *newlist);

由于它只是一个副本,因此调用者将看不到您的分配结果。您在这里似乎想要的是通过引用传递指针 - 为此,您需要一个指向指针的指针:

int takeEven(int *nums, int numelements, int **newlist) {
    *newlist = malloc(numelements * sizeof **newlist); // apply * to newlist
    ...
}

int n = takeEven(nums, sizeof(nums) / sizeof(*nums), &evenNums);

并且不要忘记free

free(evenNums);

You're passing a pointer by value here:

int n = takeEven(nums, sizeof(nums) / sizeof(*nums), evenNums);

Which means that a copy of the pointer is made within that function. You then overwrite that copy:

newlist = malloc(numelements * sizeof *newlist);

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:

int takeEven(int *nums, int numelements, int **newlist) {
    *newlist = malloc(numelements * sizeof **newlist); // apply * to newlist
    ...
}

int n = takeEven(nums, sizeof(nums) / sizeof(*nums), &evenNums);

And don't forget to free:

free(evenNums);
幻梦 2024-08-19 01:48:43

在 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 to int** as the third parameter.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文