定义函数内数组指针
我不明白为什么ARR没有指向我已在功能测试中取得的数组:定义函数内数组指针
void test(int *arr)
{
int tmp[] = {2,4};
arr = tmp;
printf("%d %d\n",arr[0],arr[1]);
}
int main()
{
int *arr;
test(arr);
printf("%d %d\n",arr[0],arr[1]);
return 0;
}
当我运行这个程序我:
2 4
17744 786764
arr是指针,为什么不更新值?
更新: 我现在看到我误解了很多关于指针和函数本地变量的问题。已经更新我的小笨笨的脚本,以适用的东西:
#include <stdio.h>
#include <stdlib.h>
void test(int *arr){
arr[0] = 123;
arr[1] = 321;
printf("%d %d\n",arr[0],arr[1]);
}
int main()
{
int arr[2];
test(arr);
printf("%d %d\n",arr[0],arr[1]);
return 0;
}
它因为在C中的参数通过值传递。 arr
您正在通过main
只是复制到功能参数arr
。
作业arr = tmp;
使arr
指向新位置。 现在arr
指向一个自动局部变量,并且一旦函数达到其结尾就不会存在。
因此,在main
printf("%d %d\n",arr[0],arr[1]);
的语句调用未定义的行为。
你的函数改为
void test(int **arr) // Change parameter to pointer to pointer to int
{
int *tmp = malloc(2*sizeof(int)); // Allocate memory dynamically
tmp[0] = 2;
tmp[1] = 4;
*arr = tmp;
printf("%d %d\n", (*arr)[0], (*arr)[1]);
}
和main
称呼其为
test(&arr);
这是因为在C参数通过值通过,这意味着它们的值复制和功能只有副本。修改副本当然不会修改原始内容。在main
函数中,当test
返回时变量仍将未初始化,导致未定义行为当您试图对其进行解引用时。
C没有通过引用,但它可以使用指针进行仿真。在你的情况下,你必须传递一个指针指向指针。
但是,这并不是全部,你尝试设置指向一个局部变量的指针,局部变量,以及本地。它们的生命周期在函数返回时结束,并且一旦函数返回,指向它们的指针就不会有效。
有两种方法可以解决这两个问题。第一个问题是通过使用地址的操作者将指针传递到指针解决,即
test(&arr);
的test
功能必须相应地修改以处理指针指向int
。
第二个问题可以通过几种方法解决。最简单的方法是延长变量的生命周期,以便即使在函数返回后,它也会继续生存。基本上只有两种方法:将变量设置为全局变量,或将其设置为局部变量static
。解决第二个问题的另一种方法是使用malloc
动态分配数组,但是一旦完成了该操作,您就必须记住free
以避免内存泄漏。
您通过值传递指针(C已仅由值通过),即指针的副本被创建指向整数数组。因此,有在指针的初始值没有变化在main
。
如果你愿意,你需要传递指针的地址,但在这种情况下,也访问它在main
也会造成问题,因为tmp
是一个局部变量,其范围将只保持有限的功能test
。
所以在main
当您尝试打印指针的内容(这是未初始化)将调用未定义行为。
-
参数按值传递。因此,您只修改副本,而不是实际参数。要真正修改
main
中的arg
,请使用指向指针的指针。
定义你的函数是这样的:void test(int** arr)
,并取消对它的引用的函数从
main
修改arr
。此外,呼叫test
这样,而不是:test(&arr);
-
自动变量超出范围的功能已经恢复,并给他们的任何进一步的访问是不确定的行为。这意味着使用
main
中的数组也是未定义的。
为了防止这种情况,你可以使阵列static
:static int tmp[] = { 0, 2 };
就这样,
tmp
初始化只一次和存在在整个运行,因此不未定义的行为。
因为你是按值传递指针 - 所以你只能改变它在你的'test'功能的本地副本... – dragosht
以及如何将arr'的''在副本main'得到更新? –