2

I have the following minimal example and I don't get, why my struct sizes are wrong. I'm expecting the output to be 50, instead I get 1. What am I doing wrong?

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

typedef struct prod {
    char *x;
} prod_t;

typedef struct obj {
    prod_t *things;
} obj_t;


#define LARGE_BUF 100
#define CHAR_BUF 20


obj_t *func1(obj_t *t) {
    t->things = malloc(sizeof(prod_t) * LARGE_BUF);

    for (uint16_t i = 0; i < 50; i++) {
        t->things[i].x = malloc(sizeof(char) * CHAR_BUF);
        t->things[i].x = "hello";
    }

    return t;
}

int main(int argc, char **argv) {
    obj_t *var = malloc(sizeof(obj_t));

    var = func1(var);

    printf("%lu\n", sizeof(var->things)/sizeof(var->things[0]));

    return 0;
}

Since I don't have the number of entries, the function generated for me (it's 50 now, but it could change dynamically), how do I free(..) this up?

Is the only option to introduce a field in the struct, to keep track of the actual array size?

Daniel
  • 157
  • 2
  • 12
  • 4
    Yes............ – user253751 Feb 02 '18 at 01:25
  • 1
    The most sensible option is to add a field that tracks the size of the array. You might want to add two fields, in fact, one to record the number of items allocated for the array and one to record the number in use. That way you can optimize how you grow your array, rather than reallocating every time you need to add something. Alternatives include simply keeping the size separately from the structure. Such alternatives are probably not a good idea. – Jonathan Leffler Feb 02 '18 at 01:42
  • 2
    Note that `sizeof array / sizeof array[0]` works only when `array` is an actual array, this doesn't work for pointers. If you have pointers and/or are passing arrays to functions, you need to pass the length to the function or store it somewhere else. – Pablo Feb 02 '18 at 02:04
  • 1
    Curious, why did you choose to use `"%lu"` to match `sizeof(var->things)/sizeof(var->things[0])`? – chux - Reinstate Monica Feb 02 '18 at 02:54
  • Good to know. @chux did that because the compiler told me it's better than a %d – Daniel Feb 02 '18 at 05:25
  • 1
    @Daniel Fair enough, Try `printf("%zu\n", sizeof(...` next time. Better not to guess. Research `printf()`. – chux - Reinstate Monica Feb 02 '18 at 06:07
  • 1
    @chux gonna keep that in mind, thanks for the hint to %zu – Daniel Feb 02 '18 at 06:23

1 Answers1

4

Yes you will need to add another member to the struct. For example a string wrapper type keeps track of the number of characters in it:

typdef struct {
    char *base;
    size_t n;
} string;

Notice n is of size_t, not int.

lost_in_the_source
  • 10,998
  • 9
  • 46
  • 75