eat_a_lemon
eat_a_lemon

Reputation: 3208

C struct pointer iteration

I did not expect to be able to increment a pointer to a struct in a memory block of structs. But it seems to work. Is there any case where this does not work? If I create a "list" of structs then I should always be able to increment the pointer to them and C will figure out how many bytes to move by?

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

struct User {
    int id;
    char name[32];
    float net_worth;
};
typedef struct User User;


int main(int argc, char** argv) {
    User* u1 = (User*)malloc(sizeof(User));
    u1->id = 1;
    strcpy(u1->name, "Mike");
    u1->net_worth = 43.45;
    User* u2 = (User*)malloc(sizeof(User));
    u2->id = 2;
    strcpy(u2->name, "Pablo");
    u2->net_worth = -2.00;
    User* u3 = (User*)malloc(sizeof(User));
    u3->id = 3;
    strcpy(u3->name, "Frederick");
    u3->net_worth = 7329213.45;

    User** users = (User**)malloc(sizeof(User)*10);
    *users = u1;
    printf("%s\n", ((User*)(*users))->name);
    *users++;
    *users = u2;
    printf("%s\n", ((User*)(*users))->name);
    *users++;
    *users = u3;
    printf("%s\n", ((User*)(*users))->name);


    return 0;

}

Upvotes: 3

Views: 4565

Answers (5)

paxdiablo
paxdiablo

Reputation: 881783

Yes, this is how it's meant to work. Adding 1 to a pointer within an array will actually advance to the next element (C will adjust the memory address by the correct amount, the size of the structure).

The only time this won't work is when you go too far. A pointer is only valid (for dereferencing and pointer arithmetic) if it points to within the array or (for arithmetic only) one beyond. So:

int x[10];
int *px = &(x[9]);  // Points to last element, okay to dereference.
px++;               // Points one beyond, still okay for aritmetic.
px++;               // Don't use this for anything.

is considered undefined behaviour if you try to use the pointer afterwards.

Upvotes: 1

Karl Knechtel
Karl Knechtel

Reputation: 61597

and C will figure out how many bytes to move by?

Yes. That is why C imposes the limits that it does on what you can put in a struct: every instance of a struct of a given type has to be the same size, and the compiler must be able to figure out that size at compile-time, for this scheme to work.

Upvotes: 0

Vinicius Kamakura
Vinicius Kamakura

Reputation: 7778

Yes.

(text to fill the 30 chars post requirement)

Upvotes: 0

EboMike
EboMike

Reputation: 77752

This is very much by design. Assume you have

User userArray[16];

You could either access the second user via userArray[1], or *(userArray + 1), or get a pointer to the first element and increment it via ++.

Upvotes: 5

jforberg
jforberg

Reputation: 6762

Quite simply: yes. This is why pointers have type.

Upvotes: 3

Related Questions