【问题标题】:Error when passing pointer to array of structs将指针传递给结构数组时出错
【发布时间】:2015-07-18 04:55:23
【问题描述】:
#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 == &amp;P,应该可以吧?

【问题讨论】:

  • 但是P已经一个指针,它指向分配的内存(数组)的第一个元素。通过按原样传递指针,除了实际的指针之外,您不会复制任何内容。
  • printf("%f\n", (*a)[i].x);

标签: c arrays function pointers struct


【解决方案1】:

&amp;p 传递给函数test 意味着您正在传递一个指针,该指针指向struct Point * 类型的一个元素 数组的第一个元素。因此,只有a[0] 是有效的(因此a[0]-&gt;x),而所有其他a[i] 都是越界访问。这将调用未定义的行为。

test 函数中将a[i]-&gt;x 更改为a[0][i].x(*a)[i].x

在这种情况下使用指向指针的指针是不值得的。如果要在函数中修改传递的指针并且该修改预计会在调用者中看到,这将是值得使用的。

【讨论】:

  • 或更好的(*a)[i].x
  • @WojciechFrohmberg ,这不应该是 JoachimPileborg 在上述评论中建议的吗?
  • @CoolGuy if we have struct Point **a (*a) is dereference of a pointer [i] is read the value from the address so基本上也指针解引用......这意味着在这两个操作之后我们得到struct Point ergo 类型:我们无法访问,因为我们会得到 struct Point *...
  • @WojciechFrohmberg,我认为你是对的。那么,Joachim 的评论是错误的,因为他三次取消引用指针?
  • @CoolGuy;是的。我想他当时和我一样困惑。
【解决方案2】:

为什么要struct Point **?可以改写成一样的

void test(struct Point *a, int len)
{
   //some stuff
    printf("%f\n", a[i].x);

}

然后这样称呼它

 test(P, len);

这样,恕我直言,要求

我想传递一个指向数组的指针

也遇到了#


(#) 注意:为了严格起见,这里我们将指针传递给数组的第一个元素,但是,行为比较相等。感谢 @alk 先生的评论。

【讨论】:

  • 谢谢,所以只是为了确保在函数中没有复制,并且我对数组所做的任何更改在函数返回后仍然存在?
  • 吹毛求疵:传递指向数组第一个元素的指针的方式。这与指向数组的指针不同,后者是struct Point (*pa)[len]
  • @alk 非常正确,先生。您能否建议适当的措辞来修改我的答案?
  • 虽然使用struct point ** 没有任何好处,但OP的代码中唯一的错误是a[i]-&gt;x
  • @hacks 是的,先生。恕我直言,OP 非常关心 not make a copy 部分,而不是数据类型本身。所以,我只是试着用一种简化的方式来表达。 :-)
【解决方案3】:

应使用参数struct Point *a 传递数组。当您增加a 时,指针将移动sizeof(struct Point)

void test(const struct Point *a, int len)
{
    ...
}

【讨论】:

    【解决方案4】:

    其他答案为您提供了更好的选择。但我会把它放在这里以帮助任何人(我自己)理解为什么它是错误的。

    【讨论】:

      【解决方案5】:

      我想传递一个指向数组的指针,

      从字面上理解您的要求,您可以这样做:

      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 Ghoshanswer 建议的方式实现相同的功能(循环遍历数组的元素)。然后,您将传递一个指向数组的 1st 元素的指针,但传递一个指向数组本身的指针。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-11-02
        • 2019-05-03
        • 1970-01-01
        • 1970-01-01
        • 2020-05-15
        • 1970-01-01
        相关资源
        最近更新 更多