如何将结构分配给结构的指针数组?

时间:2017-10-27 07:26:20

标签: c++ struct

好。所以我有以下结构:

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

现在我有以下变量:

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

现在经过一些packet的操作后,我试图将它分配给一个数组单元,如下所示:

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

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

我做错了什么?

我刚开始使用C,所以我对指针和地址不太熟悉。

编辑:正在完成作业的功能:

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++;
    }
}

由于该值是作为函数的参数出现的,因此每次都没有新的内存地址吗?

4 个答案:

答案 0 :(得分:2)

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

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

关于packet总是有相同地址的问题,我无法确定(我的猜测是这样)但你可以检查 - 每次打印时都会打&packet的值被调用,看看它是否会改变。

P.S。 packet不是函数参数,而是本地函数变量。

答案 1 :(得分:1)

packets[0] = &pkt;

给出

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

然后

packets[1] = &pkt;

给出

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

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

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

struct pkt packets[1000];

答案 2 :(得分:1)

void A_output(struct msg message)
{
    struct pkt packet;

[...]

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

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

您需要做的是例如为packetsmalloc() {/ 1}}中的每个元素分配内存:

new

在您完成后,不要忘记struct pkt *packet = malloc(sizeof *packet); // C style // or: pkt *packet = new pkt(); // C++ style [...] // fill *packet packets[counter++] = packet; (C)或free()(C ++)所有数据包。

在旁注中,在原始代码中,广告delete是多余的。 (pkt*)已有类型&packet。但是,无论如何这都是错误的,这里并不重要。

答案 3 :(得分:0)

看起来你正在尝试创建一个结构数组。下面的代码片段创建了一个结构的本地数组,每个结构都包含一个整数数组。

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

// 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.