将指针传递给结构数组时出错
Error when passing pointer to array of structs
#include <stdio.h>
#include <stdlib.h>
struct Point {
double x;
};
void test(struct Point **a, int len)
{
int i;
printf("a = %p\n", a);
for (i = 0; i < len; ++i)
printf("%f\n", a[i]->x);
}
int main()
{
int i;
int len = 4;
struct Point *P;
P = malloc(len*sizeof(struct Point));
for (i = 0; i < len; ++i) {
P[i].x = i;
printf("%f\n", P[i].x);
}
printf("&P = %p\n", &P);
test(&P, len);
return 0;
}
我正在尝试将一个结构数组传递给一个函数(我想传递一个指向该数组的指针,而不是复制)。当我尝试在函数内部使用数组时,出现访问冲突。这样做的正确方法是什么?我究竟做错了什么? a == &P
,应该可以吧?
将 &p
传递给函数 test
意味着您将指针传递给 一个元素 类型 [=12] 的数组的第一个元素=].因此,只有 a[0]
是有效的(因此 a[0]->x
),所有其他 a[i]
都是越界访问。这将调用未定义的行为。
在test
函数中将a[i]->x
更改为a[0][i].x
或(*a)[i].x
。
在这种情况下使用指针指向指针是不值得的。如果要在函数中修改传递的指针并且希望在调用者中看到该修改,那么这将是值得使用的。
为什么要 struct Point **
?您可以重写为
void test(struct Point *a, int len)
{
//some stuff
printf("%f\n", a[i].x);
}
并这样称呼它
test(P, len);
这样,恕我直言,要求
I want to pass a pointer to the array
也会#.
(#) 注意:为了严格起见,这里我们将 指针传递给数组的第一个元素 ,但是,行为比较相等。感谢@alk先生的评论
数组应该使用参数struct Point *a
传递。当您增加 a
时,指针将移动 sizeof(struct Point)
。
void test(const struct Point *a, int len)
{
...
}
其他答案会更好alternatives.But我把这个放在这里是为了帮助任何人(我自己)理解为什么它是错误的。
I want to pass a pointer to the array,
从字面上理解您的要求,您可以这样做:
void test(size_t len, struct Point (*a)[len])
{
size_t i;
printf("a = %p\n", (void *) a);
for (i = 0; i < len; ++i)
printf("%f\n", (*a)[i].x);
}
并这样称呼它:
size_t len = 4;
struct Point * p = malloc(len * sizeof *p);
for (i = 0; i < len; ++i) {
p[i].x = i;
printf("%f\n", p[i].x);
}
printf("p = %p\n", (void *) p);
printf("&p = %p\n", (void *) &p);
test(len, &p);
您也可以按照 Sourav Ghosh's 提出的方法实现相同的功能(遍历数组的元素)。然后,您将传递一个指向数组的 1st 元素的指针,但传递一个指向数组本身的指针。
#include <stdio.h>
#include <stdlib.h>
struct Point {
double x;
};
void test(struct Point **a, int len)
{
int i;
printf("a = %p\n", a);
for (i = 0; i < len; ++i)
printf("%f\n", a[i]->x);
}
int main()
{
int i;
int len = 4;
struct Point *P;
P = malloc(len*sizeof(struct Point));
for (i = 0; i < len; ++i) {
P[i].x = i;
printf("%f\n", P[i].x);
}
printf("&P = %p\n", &P);
test(&P, len);
return 0;
}
我正在尝试将一个结构数组传递给一个函数(我想传递一个指向该数组的指针,而不是复制)。当我尝试在函数内部使用数组时,出现访问冲突。这样做的正确方法是什么?我究竟做错了什么? a == &P
,应该可以吧?
将 &p
传递给函数 test
意味着您将指针传递给 一个元素 类型 [=12] 的数组的第一个元素=].因此,只有 a[0]
是有效的(因此 a[0]->x
),所有其他 a[i]
都是越界访问。这将调用未定义的行为。
在test
函数中将a[i]->x
更改为a[0][i].x
或(*a)[i].x
。
在这种情况下使用指针指向指针是不值得的。如果要在函数中修改传递的指针并且希望在调用者中看到该修改,那么这将是值得使用的。
为什么要 struct Point **
?您可以重写为
void test(struct Point *a, int len)
{
//some stuff
printf("%f\n", a[i].x);
}
并这样称呼它
test(P, len);
这样,恕我直言,要求
I want to pass a pointer to the array
也会#.
(#) 注意:为了严格起见,这里我们将 指针传递给数组的第一个元素 ,但是,行为比较相等。感谢@alk先生的评论
数组应该使用参数struct Point *a
传递。当您增加 a
时,指针将移动 sizeof(struct Point)
。
void test(const struct Point *a, int len)
{
...
}
其他答案会更好alternatives.But我把这个放在这里是为了帮助任何人(我自己)理解为什么它是错误的。
I want to pass a pointer to the array,
从字面上理解您的要求,您可以这样做:
void test(size_t len, struct Point (*a)[len])
{
size_t i;
printf("a = %p\n", (void *) a);
for (i = 0; i < len; ++i)
printf("%f\n", (*a)[i].x);
}
并这样称呼它:
size_t len = 4;
struct Point * p = malloc(len * sizeof *p);
for (i = 0; i < len; ++i) {
p[i].x = i;
printf("%f\n", p[i].x);
}
printf("p = %p\n", (void *) p);
printf("&p = %p\n", (void *) &p);
test(len, &p);
您也可以按照 Sourav Ghosh's