You can use a flexible array. It must be the last data member of a structure.
struct person{
int c;
char name[];
};
The memory for a structure with a flexible array has to be allocated dynamically.
From the C Standard (6.7.2.1 Structure and union specifiers)
the flexible array member is ignored. In particular, the size of the
structure is as if the flexible array member were omitted except that
it may have more trailing padding than the omission would imply. Howev
er, when a . (or ->) operator has a left operand that is (a pointer
to) a structure with a flexible array member and the right operand
names that member, it behaves as if that member were replaced with the
longest array (with the same element type) that would not make the
structure larger than the object being accessed; the offset of the
array shall remain that of the flexible array member, even if this
would differ from that of the replacement array. If this array would
have no elements, it behaves as if it had one element but the behavior
is undefined if any attempt is made to access that element or to
generate a pointer one past it.
And there is an example of its using
20 EXAMPLE 2 After the declaration:
struct s { int n; double d[]; };
the structure struct s has a flexible array member d. A typical way to use this is:
int m = /* some value */;
struct s *p = malloc(sizeof (struct s) + sizeof (double [m]));
and assuming that the call to malloc succeeds, the object pointed to by p behaves, for most purposes, as if
p had been declared as:
struct { int n; double d[m]; } *p;
(there are circumstances in which this equivalence is broken; in particular, the offsets of member d might
not be the same).
Or you could declare a pointer to char and dynamically allocate only the array itself
struct person{
int c;
char *name;
};