-5

Okay. So I have the following struct:

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

Now I have the following variables:

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

Now after a few manipulations of packet I am trying to assign it to an array cell as follows:

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

But that is somehow changing all the cells of the array upon a new assignment to the value of the new assignment.

What am I doing wrong?

I have just started off with C, so I am not so familiar with pointers and addresses.

EDIT: The function in which the assignment is being done:

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

Since the value is coming as a parameter of a function, doesn't it have a new memory address every time?

20
  • Okay. So you don't understand what a pointer is? Commented Oct 27, 2017 at 7:27
  • You are assigning the same address for all packets, I don't think that's yur intent. Commented Oct 27, 2017 at 7:27
  • Time to take a deep breath and re-read the C book. Don't rush. Commented Oct 27, 2017 at 7:28
  • 1
    @Manic "Can't use vector." Silly restriction. Commented Oct 27, 2017 at 7:36
  • 1
    @Manic well, now it's possible to answer, which I did. Please keep in mind for the next time you ask a question to create a minimal reproducible example (if it's a question seeking debugging help) from the beginning, so you won't get these downvotes. Commented Oct 27, 2017 at 8:09

4 Answers 4

2

Well, all the cells in the array have the value of &packet, which is a single value. They all point to the same address, so of course they all point to the same value.

You can dynamically allocate the memory, or much better, just make packets a pkt[] - an array of regular packets and then assignment to one of the cells will preform copy of all the values to another memory, not copy of pointer.

As for the question if packet always has the same address, I cannot know for sure (My guess is that it does) but you could check - print the value of &packet every time the function is called and see if it changes.

P.S. packet isn't a function argument, but a local function variable.

Sign up to request clarification or add additional context in comments.

8 Comments

packet is coming as a parameter of a function. So isn't it coming as a new value every time?
It depends. Could you include the full function and the function that calls it?
@Manic that's why you're supposed to create a minimal reproducible example: We can't know! -- Neo, don't answer questions that are (still?) unclear, see How to answer -- "answer well-asked questions".
@FelixPalmen Edited the post.
@Manic Where is packets defined?
|
1
void A_output(struct msg message)
{
    struct pkt packet;

[...]

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

This last line assigns the address of a variable with automatic storage duration (a local variable) to an object with static storage duration (a global). Once your function exits, the variable with automatic storage duration doesn't exist anymore, therefore the pointer doesn't point to a valid location. Using this pointer later is undefined behavior, but it's quite likely that your function reuses the same memory location for your struct pkt packet every time it is invoked, leading to the behavior you describe.

What you have to do is for example allocate memory for every element in packets with malloc() or new:

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

[...] // fill *packet

packets[counter++] = packet;

Don't forget to free() (C) or delete (C++) all the packets when you're done.

On a side note, in your original code, the cast (pkt*) is redundant. &packet already has the type struct pkt *. But as this is wrong anyways, it doesn't matter much here.

Comments

1
packets[0] = &pkt;

Gives

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

Then

packets[1] = &pkt;

Gives

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

There is one underlying object (pkt), which is referred to in two places in the array.

If you want their values to be distinct, then make the array an array of full members.

struct pkt packets[1000];

Comments

0

It looks like you're attempting to create an array of structures. The below code snippet creates a local array of structures which each contain an array of integers.

The method acts on the array of structures individually, assigning unique values to the integer array inside.

// 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);
         }
     }
}

Since the value is coming as a parameter of a function, doesn't it have a new memory address every time?

The function parameter(s) will be pushed to the stack when the function is called. If you want the variable you are parsing to retain its value after you operate on it, use a pointer argument instead.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.