我很困惑它是否有效(在C中)将指针传递给已按如下方式启动的数组(例如,在堆栈上的编译时):
int a[] = {1, 2, 3};
my_func(&a);
void my_func(int **a)
{
int *tmp = *a; /* this statement fixes the problem */
printf("%d %d %d", (*a)[0], (*a)[1], (*a)[2]); /*doesn't work */
printf("%d %d %d", tmp[0], tmp[1], tmp[2]); /*does work */
}
当我使用gdb逐步执行此操作时,我无法从'inside'my_func'中'看到'任何值(* a)[0]等。 e.g。
(gdb) p (*a)[0]
Cannot access memory at address 0x0
我在想我可能对堆栈而不是堆上的数组能做什么和不能做什么有根本的误解?
我希望不是这种情况,因为我的单元测试非常方便在示例中声明堆栈上的数组,但是我需要测试期望指向int的指针的函数。
注意我收到编译器警告如下:
test_utility.c:499:5: warning: passing argument 1 of ‘int_array_unique’ from incompatible pointer type [enabled by default]
../src/glamdring2.h:152:5: note: expected ‘int **’ but argument is of type ‘int (*)[12]’
但我认为将*a[]
与**a
混合可以吗?也许不是?它们不相同吗?
答案 0 :(得分:4)
a []是一个数组,而不是指针(“不是左值”);在你的函数调用中
func( &a);
& a衰减指向int的指针; & a是不指向int的指针。为什么? 没有指针指向。
函数原型
void func( int **p);
需要一个指向int的指针,这个指针不适合被调用的函数,并且指向int作为参数,就像你一样。
更新:我不知道OP的意图是什么,所以这只是猜测......
void my_func(int *a);
int a[] = {1, 2, 3};
my_func(a); /* note: this is equivalent to my_func( &a ); */
void my_func(int *a)
{
printf("%d %d %d\n", a[0], a[1], a[2] );
}
答案 1 :(得分:1)
printf("%p vs %p vs %p\n",&a,&a[0],a);
& a& a [0]和a - 都是一样的 - 数组中第一个int的地址
void my_func(int **a);
int main(int ac, char *av[]) {
int a[] = {1, 2, 3};
int *p = a;
printf("%p vs %p vs %p\n",&a,&a[0],a); //are all the same - the address of the first int in the array
my_func(&p);
return 0;
}
void my_func(int **a) {
printf("%d %d %d", (*a)[0], (*a)[1], (*a)[2]);
}
http://www.ibiblio.org/pub/languages/fortran/append-c.html
http://publications.gbdirect.co.uk/c_book/chapter5/arrays_and_address_of.html
答案 2 :(得分:0)
在堆栈上声明一个数组并将其地址传递给函数是完全没问题的,只要该函数不会尝试存储对该数组的引用以供以后使用。
不知道为什么你要为参数添加额外的间接。为什么不直接声明my_func
将int*
作为参数,只需将a
作为参数传递?这不太可能混淆调试器。
答案 3 :(得分:0)
您假设sizeof(int) == sizeof(void *)
。这可能不是真的。我不确定这是否是您的问题的原因,但至少我会先添加一个运行时测试断言假设,或者更好地从int更改为指针。