1

Alright, so here goes. I am trying to do a switch over a string value in C, as described here. However, the array of structs does not seem be initialised properly. My (simplified) program looks as follows:

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

#define BADKEY     -1
#define VALUE       1
#define OTHERVALUE  2
#define FOOVALUE    3

#define NREQKEYS (sizeof(lookuptable)/sizeof(symstruct_t))

typedef struct {
    char *key;
    int val;
} symstruct_t;

static symstruct_t lookuptable[] = {
    { "some value here", VALUE },
    { "other value",     OTHERVALUE },
    { "yet another one", FOOVALUE }
};

int main(void) {
    // Testing...
    int i;
    for (i = 0; i < NREQKEYS; i++) {
        symstruct_t *sym = lookuptable + i * sizeof(symstruct_t);
        printf("%d: key = '%s', val = %d.\n", i, sym->key, sym->val);
    }
}

Then, I compile the above program as follows (it is saved in test.c obviously), on Debian Jessie (currently testing). The version of gcc is gcc version 4.7.2 (Debian 4.7.2-5). Compiling gives no warnings or errors.

gcc test.c -o test -std=gnu99

Now, I would expect that this simple program simply prints out the values that I initialise the array with. However, the output is this:

$ ./test 
0: key = 'some value here', val = 1.
1: key = '(null)', val = 0.
2: key = '(null)', val = 0.

The two possible causes I can think of are that either my loop is incorrect, which makes no sense to me, or that the initialisation somehow is wrong. However, searching this site and in general on Google did not help me. I am open to other solutions as well, but also interested in just why this does not work.

Thanks!

Community
  • 1
  • 1
Just a student
  • 10,560
  • 2
  • 41
  • 69

4 Answers4

5

This expression is wrong:

lookuptable + i * sizeof(symstruct_t)

It's enough with

lookuptable + i

The compiler already knows the size of each member in the array, so it knows that adding i to the array means that it will use index i, i.e. it's the same thing as &lookuptable[i].

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • Thanks a lot for the answer (it works!) and the explanation. As soon as I can (have to wait 5 minutes), I will accept your answer :-) – Just a student May 20 '13 at 09:46
2

You don't have to scale the pointer to the size of the object that it points to lookuptable + i * sizeof(symstruct_t); ; the compiler does that for you automatically.

ptr+1 will be interpreted by the compiler as a pointer to the the next object after *ptr ; if ptr points to the first array element, ptr+1 will point to the second.

for (i = 0; i < NREQKEYS; i++) {
        symstruct_t *sym
        sym = lookuptable + i;
        printf("%d: key = '%s', val = %d.\n", i, sym->key, sym->val);
    }

Or, its equivalent:

for (i = 0; i < NREQKEYS; i++) {
        symstruct_t *sym
        sym = & lookuptable[i];
        printf("%d: key = '%s', val = %d.\n", i, sym->key, sym->val);
    }

BTW: you don't need a pointer here, array indexing will work just fine:

for (i = 0; i < NREQKEYS; i++) {
        printf("%d: key = '%s', val = %d.\n", i, lookuptable[i].key, lookuptable[i].val);
    }
wildplasser
  • 43,142
  • 8
  • 66
  • 109
2

You should drop the sizeof(symstruct_t) coefficient. C and C++ pointer arithmetic does this automatically for you.

To help understand this, remember that pointer arithmetic and array access are the same thing:

Array[i] is the same as *(Array + i)

It would be inconvenient to have to write Array[i * sizeof(...)] and therefore equally inconvenient if you had to write *(Array + i * sizeof(...)).

Bathsheba
  • 231,907
  • 34
  • 361
  • 483
1
symstruct_t *sym = lookuptable + i * sizeof(symstruct_t);

should be

symstruct_t *sym = lookuptable + i;
MOHAMED
  • 41,599
  • 58
  • 163
  • 268