【问题标题】:How to assign a struct to an array of pointers of the struct? [closed]如何将结构分配给结构的指针数组? [关闭]
【发布时间】:2018-04-08 17:47:59
【问题描述】:

好的。所以我有以下结构:

struct pkt {
    int seqnum;
    int acknum;
    int checksum;
    char payload[20];
};

现在我有以下变量:

struct pkt packet;
struct pkt* packets[1000];

现在在对packet 进行了几次操作之后,我尝试将其分配给数组单元格,如下所示:

packets[counter++] = (pkt*)&packet;

但这会以某种方式将数组的所有单元格在新赋值时更改为新赋值的值。

我做错了什么?

我刚开始接触 C,所以我对指针和地址不是很熟悉。

EDIT:正在完成分配的函数:

void A_output(struct msg message)
{
    struct pkt packet;
    packet.acknum = 0;
    packet.seqnum = 0;
    memset(&packet.payload, '\0', 20);
    memcpy((char*)&packet.payload, (char*)&message.data, 20);
    memset(&packets[counter]->payload, '\0', 20);
    packets[counter++] = (pkt*)&packet;
    printAll();

    if(nextseq < winbase + winsize) {
        packets[nextseq]->seqnum = nextseq;
        setChecksum(packets[nextseq]);
        tolayer3(0, *packets[nextseq]);

        if(winbase == nextseq) 
            starttimer(0, increment);
        nextseq++;
    }
}

既然值是作为函数的参数来的,不是每次都有新的内存地址吗?

【问题讨论】:

  • 好的。所以你不明白什么是指针
  • 您为所有数据包分配相同的地址,我认为这不是您的意图。
  • 是时候深吸一口气,重新阅读 C 书了。不要着急。
  • @Manic “不能使用向量。” 愚蠢的限制。
  • @Manic 好吧,现在可以回答了,我做到了。请记住,下次您提出问题时要从头开始创建minimal reproducible example(如果是寻求调试帮助的问题),这样您就不会得到这些反对意见。

标签: c++ struct


【解决方案1】:

好吧,数组中的所有单元格的值都是&amp;packet,这是一个单一的值。它们都指向同一个地址,所以当然它们都指向同一个值。

您可以动态分配内存,或者更好的是,只需将packets 设为pkt[] - 一个常规数据包数组,然后分配给其中一个单元,会将所有值复制到另一个内存,而不是复制的指针。

至于packet 是否总是具有相同地址的问题,我无法确定(我的猜测是确实如此)但您可以检查 - 每次调用函数时打印&amp;packet 的值并查看如果它改变了。

附: packet 不是函数参数,而是局部函数变量。

【讨论】:

  • packet 作为函数的参数出现。那么它不是每次都以新价值的形式出现吗?
  • 视情况而定。你能包括完整的函数和调用它的函数吗?
  • @Manic 这就是为什么你应该创建一个minimal reproducible example:我们不知道! -- Neo,不要回答(仍然?)不清楚的问题,请参阅How to answer -- “回答好问题”。
  • @FelixPalmen 编辑了帖子。
  • @Manic packets 在哪里定义?
【解决方案2】:
void A_output(struct msg message)
{
    struct pkt packet;

[...]

    packets[counter++] = (pkt*)&packet;

最后一行将具有自动存储持续时间(局部变量)的变量的地址分配给具有静态存储持续时间(全局)的对象。一旦您的函数退出,具有自动存储持续时间的变量不再存在,因此指针不会指向有效位置。稍后使用此指针是未定义的行为,但很有可能您的函数每次调用它时都会为您的 struct pkt packet 重用相同的内存位置,从而导致您描述的行为。

例如,您需要为packets 中的每个元素分配内存,malloc()new

struct pkt *packet = malloc(sizeof *packet); // C style
// or:
pkt *packet = new pkt(); // C++ style

[...] // fill *packet

packets[counter++] = packet;

完成后不要忘记free() (C) 或 delete (C++) 所有数据包。

附带说明,在您的原始代码中,演员 (pkt*) 是多余的。 &amp;packet 已经具有 struct pkt * 类型。不过既然这样是错的,这里就无所谓了。

【讨论】:

    【解决方案3】:
    packets[0] = &pkt;
    

    给予

     +-----+           +-------+
     | 0   | ========> | [pkt] |
     +-----+           +-------+
    

    然后

    packets[1] = &pkt;
    

    给予

     +-------+              +----------+
     |    0  |  ==========> |  [pkt]   |
     +-------+         ||=> +----------+
     |    1  |  =======* 
     +-------+
    

    有一个底层对象(pkt),它在数组中的两个位置被引用。

    如果您希望它们的值不同,则将数组设为完整成员数组。

    struct pkt packets[1000];
    

    【讨论】:

      【解决方案4】:

      您似乎正在尝试创建一个结构数组。下面的代码 sn-p 创建了一个本地结构数组,每个结构都包含一个整数数组。

      该方法单独作用于结构数组,为内部的整数数组分配唯一值。

      // Structure definitions
      #define NUM_OF_VALUES 2
      #define NUM_OF_STRUCTS 5
      
      typedef struct {
          uint value[NUM_OF_VALUES];
      } Test_Struct_t;
      
      // local object
      static Test_Struct_t struct_array[NUM_OF_STRUCTS];
      
      // Function settings values in local object.
      void struct_foo(void)
      {
           for (uint idx = 0; idx < NUM_OF_STRUCTS; idx++)
           {
               for (uint jdx = 0; jdx < NUM_OF_VALUES; jdx++)
               {
                   struct_array[idx].value[jdx] = (idx + jdx);
               }
           }
      }
      

      既然值是作为函数的参数出现的,不是吗? 每次都有新的内存地址吗?

      函数调用时,函数参数将被压入堆栈。如果您希望正在解析的变量在对其进行操作后保留其值,请使用pointer argument instead.

      【讨论】:

        猜你喜欢
        • 2011-06-18
        • 1970-01-01
        • 1970-01-01
        • 2021-11-20
        • 1970-01-01
        • 1970-01-01
        • 2015-01-12
        • 2015-03-27
        • 1970-01-01
        相关资源
        最近更新 更多