Structure with another structure into it - c

How can I correctly access the price member from the category structure?
This is the code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SMAX 128
typedef struct {
int price;
char favCharacter[SMAX], edition[SMAX];
} category;
typedef struct {
char title[SMAX], fname[SMAX], lname[SMAX];
category *cat;
} book;
int main(int argc, char **argv) {
book *data = malloc(100 * sizeof(book));
(data->cat)->price = 10; //1
printf("\n\n(*(data->cat)).price is: %d%s", (data->cat)->price, "\n\n");
return 0;
}
My first attempt failed (//1)
What is the right way to solve this? (I mean to have a structure with another structure).

You are allocating memory for book, but not for the cats inside the books. Here's an example:
/* allocate a hundred books */
book *data = malloc(100 * sizeof *data);
/* allocate one cat per book */
for (i = 0; i < 100; ++i)
data[i].cat = malloc(sizeof *data[i].cat);
/* now you can use it */
for (i = 0; i < 100; ++i)
data[i].cat->price = 50;
Note: you need to add checks to make sure malloc doesn't fail before continuing using the returned memory. Also, it's best to avoid magic numbers such as 100 above. Furthermore, don't forget to free the memory later.

You are allocating an array of books in your line:
book *data = malloc(100 * sizeof(book));
So you should access an array element before accessing its contents:
data[0].cat->price = 10; // lets access element 0 for example.
But, first, you must also alloc data for the cat variable inside each array element:
for ( int i = 0; i < 100; i++ ) {
data[i].cat = malloc(sizeof(category));
}
Now you can access your elements correctly.
Don't forget to free the allocated memory.

Change
book *data = malloc(100 * sizeof(book));
(data->cat)->price = 10; //1
printf("\n\n(*(data->cat)).price is: %d%s", (data->cat)->price, "\n\n");
to
// 1. need explicit conversion
book *data = (book *) malloc(100 * sizeof(book));
// 2. allocate category for book *data
for (int i=0; i<100; i++)
data[i].cat = (category *) malloc(sizeof(category));
// 3. setting
(data[0].cat)->price = 10;
// 4. read
printf("\n\n(*(data->cat)).price is: %d%s", (data[0].cat)->price, "\n\n");

Related

Accessing members of dynamically allocated array of pointers to structs

I need to have a global dynamic array of pointers, in which I will store my structs, beacuse later I will need to iterate through this array to list all the stored information, I also need to be able to read the name, age and job variables from the console, and store them in a person_t in the iterator array.
#include <stdio.h>
#include <stdlib.h>
typedef struct Person
{
char name[30];
int age;
char job[30];
} person_t;
person_t **iterator;
int capacity = 10;
int size = 0;
int main()
{
int i;
*iterator = (person_t *)malloc(capacity * sizeof(person_t));
for (i = 0; i < capacity; ++i)
{
person_t p;
p.age = i;
*iterator[i] = p;
}
return 0;
}
I get no errors/warnings compiling this code (gcc -ansi -pedantic -Wall -Wextra), but when I try to run it, I get a Segmentation fault immediately.
When you do this:
*iterator = (person_t *)malloc(capacity * sizeof(person_t));
You're deferencing iterator, however as a file-scope pointer variable it's initialized to NULL. Attempting to dereference a NULL pointer invokes undefined behavior.
I suspect what you really want is an array of structs, not an array of pointers to structs. That being the case, define iterator as:
person_t *iterator;
Then you allocate memory for it like this:
iterator = malloc(capacity * sizeof(person_t));
Then assign to array elements like this:
iterator[i] = p;
Your stated purpose is to create a "global dynamic array of pointers, in which I will store my structs". The following modification of your code (see comments) will do this:
person_t p[10] = {0};
int main()
{
int i;
// with declaration: person_t **iterator = NULL;,
//following is all that is needed to create an array of pointers:
iterator = malloc(capacity * sizeof(person_t *));//no need to cast return of malloc
for (i = 0; i < capacity; ++i)
{
//person_t p;//moved to scope that will exist outside of main()
p[i].age = i;
iterator[i] = &p[i];//assign the address of the object to the pointer
//iterator[i] is the ith pointer in a collection of
//pointers to be assigned to point to
//instances of struct person_t
}
//Once all fields are populated (to-do), the following will display the results:
for (i = 0; i < capacity; ++i)
{
printf("%d) Name: %s Age: %d Job: %s\n", i, iterator[i]->name,iterator[i]->age,iterator[i]->job);
}
return 0;
}
you are not allocating memory correctly
First you need to allocate memory for a pointer which can store capacity number of address i.e done through iterator = malloc(capacity * sizeof(person_t*)); and then you need to allocate memory for holding each structure element i.e iterator[i] = malloc(sizeof(person_t));
all the malloc'ed memory should be free'd once we are done with it.
Also, have not done the error check for malloc's , that is left as an exercise for you.
int main()
{
int i;
// test data
char *names[] = {"ABC", "DEF"};
char *jobs[] = {"Accountant", "Security"};
int ages[] = {50, 60};
// first allocate memory for iterator , which can hold pointers to store iterator poniters
iterator = malloc(capacity * sizeof(person_t*));
for (i = 0; i < capacity; ++i)
{
// now allocate memory for individual iterator
iterator[i] = malloc(sizeof(person_t));
strcpy(iterator[i]->name,names[i]);
iterator[i]->age = ages[i];
strcpy(iterator[i]->job, jobs[i]);
}
for (i = 0; i < capacity; ++i)
{
printf("name = %s ", iterator[i]->name);
printf("Age = %d ", iterator[i]->age);
printf("Job = %s\n", iterator[i]->job);
}
return 0;
}

Freeing structure elements in C

I have a structure:
struct student{
int roll_no;
char *name = malloc(25 * sizeof(char));;
char *phone_no = malloc(10 * sizeof(char));;
char *dob = malloc(10 * sizeof(char));;
}*s1;
int main(){
s1 = malloc(5 * sizeof(student)); //array of student
//.....
}
What is appropriate code for the complete loop for allocating an array of student of size 'n' and then de-allocating it afterwards?
Note: The question here deals with allocation and de-allocation of elements of the instance of a structure.
This...
typedef struct student{
int roll_no; // (the following illegal syntax commented out)
char *name; // = malloc(25 * sizeof(char));;
char *phone_no; // = malloc(10 * sizeof(char));;
char *dob; // = malloc(10 * sizeof(char));;
}*s1;
...from what is being described as the need, (minus the illegal assignment statements) could probably better be formed as:
typedef struct {
int roll_no;
char *name; //needs memory
char *phone; //needs memory
char *dob; //needs memory
}STUDENT;
Then, use the new variable type: STUDENT, to create the instances of the struct as needed. Your OP indicates you need 5:
STUDENT s[5]; //Although this array needs no memory, the
//members referenced by it do
//(as indicated above)
Now, all that is necessary is to create memory for the 3 members that require it, in each of the 5 instances.
for(i=0;i<5;i++)
{
s[i].name = calloc(80, 1); //calloc creates AND initializes memory.
s[i].phone = calloc(20, 1); //therefore safer than malloc IMO.
s[i].dob = calloc(20, 1); //Also, change values as needed to support actual
//length needs for name, phone and dob
}
// Use the string members of s[i] as you would any other string, But do not
// forget to free them when no longer needed.
...
for(i=0;i<5;i++)
{
free(s[i].name);
free(s[i].phone);
free(s[i].dob);
}
Note, because of the way the array s is created in this example, i.e. with memory on the stack instead of the heap, there is no need to free it.
One other note, the example code above focused on a method to create memory for the char * members of your struct array, but when actually coding for keeps, the return of [m][c][re]alloc should always be checked that memory was created before trying to use the variable. For example:
s[i].name = calloc(80, 1);
if(!s[i].name) //checking that memory was created
{
;//if failed, then handle error.
}
...
In addition to ryyker's answer, if you want to do it dynamically:
#include <stdlib.h>
struct student{
int roll_no;
char *name;
char *phone;
char *dob;
};
int main()
{
int i, student_count = 5;
struct student ** s = malloc(sizeof(struct student *) * student_count);
if (s)
{
for (i = 0; i < student_count; ++i)
{
s[i] = malloc(sizeof(struct student));
if (s[i])
{
//set up student's members
}
}
for (i = 0; i < student_count; ++i)
{
//free student's members before the next line.
free(s[i]);
}
free(s);
}
return 0;
}
You must free everything you malloc, and as mentioned in the comments you cannot malloc inside the struct.
#include <stdio.h>
#include <stdlib.h>
#define NUM_STUDENTS 5
struct student{
int roll_no;
char *name;
char *phone;
char *dob;
};
int main(void)
{
int i;
// if this was me, I would simply replace this with
// struct student s[NUM_STUDENTS];, but the goal here is to illustrate
// malloc and free
struct student* s = malloc(sizeof(struct student) * NUM_STUDENTS);
if (s == NULL) // handle error
for (i=0; i<NUM_STUDENTS; i++)
{
// sizeof(char) is guaranteed to be 1, so it can be left out
s[i].name = malloc(25);
if (s[i].name == NULL) // handle error
s[i].phone = malloc(10);
if (s[i].phone == NULL) // handle error
s[i].dob = malloc(10);
if (s[i].dob == NULL) // handle error
}
// do stuff with with the data
....
// time to clean up, free in the reverse order from malloc
for (i=0; i<NUM_STUDENTS; i++)
{
// the dob, phone, name order here isn't important, just make sure you
// free each struct member before freeing the struct
free(s[i].dob);
free(s[i].phone);
free(s[i].name);
}
// now that all the members are freed, we can safely free s
free(s);
return 0;
}
User Abhijit gave an answser that was in the right direction, but not complete. His answer should have been:
typedef struct STUDENT{
int roll_no;
char *name;
char *phone;
char *dob;
}student;
void example(int n_students)
{
student **s;
int i;
s= malloc(n_students * sizeof(student *));
for (i=0; i<n_students; i++)
{
s[i]= malloc(sizeof(student));
s[i]->name= malloc(25);
s[i]->phone= malloc(10);
s[i]->dob= malloc(10);
}
// now free it:
for (i=0; i<n_students; i++)
{
free(s[i]->name);
free(s[i]->phone);
free(s[i]->dob);
free(s[i]);
}
free(s);
}

2 dimensional array in struct

I have to implement game of life, it is almost complete, the last thing I want to do is to allocate my field dynamical. I'm working under Windows, got no Valgrind and I don't no what's the error in my code. Eclipse shows only that the process is not functional anymore.
Can anyone tell me, what's the problem in my code? Or maybe I don't need a 2 dim. array for game of life field?
struct game_field {
int length;
int **field;
};
static struct game_field *new_game_field(unsigned int l) {
struct game_field *pstField;
pstField = calloc(1, sizeof(struct game_field));
pstField->length = l;
pstField->field = malloc(l * sizeof(int*));
for( int i = 0; i < l; i++ ) {
pstField->field[i] = malloc(l * sizeof(int));
if(NULL == pstField->field[i]) {
printf("No memory for line %d\n",i);
}
}
return pstField;
}
You should think a little bit about the structures and what you are storing.
For the game of life you need to know the state of the cell on the board which is indicated by and integer so your struct should become:
struct game_field {
int length;
int *field;
};
And once you know the dimensions of the field you should allocate it once:
struct game_field *gf = calloc(1, sizeof(struct game_field));
gf->length = <blah>;
gf->field = malloc(gf->length*gf->length*sizeof(int));
This way you have an array of integers that you can use as your board.
The first malloc should be:
pstField->field = malloc(l * sizeof(int*));
Your array is int**, so the first level of allocation is an int*.
Edit: Well, I've tested your code and it does not crash for me. The problem might be somewhere else.
Here's a modification of your code that allocates the field in one block, but still lets you use array brackets for both dimensions:
struct game_field {
int length;
int **field;
};
static struct game_field *new_game_field(unsigned int len)
{
struct game_field *pstField;
pstField = malloc(sizeof(struct game_field));
pstField->length = len;
/* allocate enough space for all the row pointers + the row contents */
pstField->field = malloc((len * sizeof(int *)) + (len * len * sizeof(int)));
/* point the row pointers (at the start of the block) at the row contents
* (further into the block). */
for (int i = 0; i < len; i++)
pstField->field[i] = (int *)(&field[len]) + (i * len);
return pstField;
}
This way you can free the field in one shot:
void free_game_field(struct game_field *gf)
{
free(gf->field);
free(gf);
}
And you can keep the bracket notation to access the elements:
int row7col3 = gf->field[7][3];
Note that what you have (here as well as in your original code) is not exactly a two-dimensional array, but an array of pointers to arrays of integers
(there is a difference, but the arr[x][y] notation can work for either one).

How to allocate and deallocate heap memory for 2D array?

I'm used to PHP, but I'm starting to learn C. I'm trying to create a program that reads a file line by line and stores each line to an array.
So far I have a program that reads the file line by line, and even prints each line as it goes, but now I just need to add each line to an array.
My buddy last night was telling me a bit about it. He said I'd have to use a multidimensional array in C, so basically array[x][y]. The [y] part itself is easy, because I know the maximum amount of bytes that each line will be. However, I don't know how many lines the file will be.
I figure I can make it loop through the file and just increment an integer each time and use that, but I feel that there might be a more simple way of doing it.
Any ideas or even a hint in the right direction? I appreciate any help.
To dynamically allocate a 2D array:
char **p;
int i, dim1, dim2;
/* Allocate the first dimension, which is actually a pointer to pointer to char */
p = malloc (sizeof (char *) * dim1);
/* Then allocate each of the pointers allocated in previous step arrays of pointer to chars
* within each of these arrays are chars
*/
for (i = 0; i < dim1; i++)
{
*(p + i) = malloc (sizeof (char) * dim2);
/* or p[i] = malloc (sizeof (char) * dim2); */
}
/* Do work */
/* Deallocate the allocated array. Start deallocation from the lowest level.
* that is in the reverse order of which we did the allocation
*/
for (i = 0; i < dim1; i++)
{
free (p[i]);
}
free (p);
Modify the above method. When you need another line to be added do *(p + i) = malloc (sizeof (char) * dim2); and update i. In this case you need to predict the max numbers of lines in the file which is indicated by the dim1 variable, for which we allocate the p array first time. This will only allocate the (sizeof (int *) * dim1) bytes, thus much better option than char p[dim1][dim2] (in c99).
There is another way i think. Allocate arrays in blocks and chain them when there is an overflow.
struct _lines {
char **line;
int n;
struct _lines *next;
} *file;
file = malloc (sizeof (struct _lines));
file->line = malloc (sizeof (char *) * LINE_MAX);
file->n = 0;
head = file;
After this the first block is ready to use. When you need to insert a line just do:
/* get line into buffer */
file.line[n] = malloc (sizeof (char) * (strlen (buffer) + 1));
n++;
When n is LINE_MAX allocate another block and link it to this one.
struct _lines *temp;
temp = malloc (sizeof (struct _lines));
temp->line = malloc (sizeof (char *) * LINE_MAX);
temp->n = 0;
file->next = temp;
file = file->next;
Something like this.
When one block's n becomes 0, deallocate it, and update the current block pointer file to the previous one. You can either traverse from beginning single linked list and traverse from the start or use double links.
There's no standard resizable array type in C. You have to implement it yourself, or use a third-party library. Here's a simple bare-bones example:
typedef struct int_array
{
int *array;
size_t length;
size_t capacity;
} int_array;
void int_array_init(int_array *array)
{
array->array = NULL;
array->length = 0;
array->capacity = 0;
}
void int_array_free(int_array *array)
{
free(array->array);
array->array = NULL;
array->length = 0;
array->capacity = 0;
}
void int_array_push_back(int_array *array, int value)
{
if(array->length == array->capacity)
{
// Not enough space, reallocate. Also, watch out for overflow.
int new_capacity = array->capacity * 2;
if(new_capacity > array->capacity && new_capacity < SIZE_T_MAX / sizeof(int))
{
int *new_array = realloc(array->array, new_capacity * sizeof(int));
if(new_array != NULL)
{
array->array = new_array;
array->capacity = new_capacity;
}
else
; // Handle out-of-memory
}
else
; // Handle overflow error
}
// Now that we have space, add the value to the array
array->array[array->length] = value;
array->length++;
}
Use it like this:
int_array a;
int_array_init(&a);
int i;
for(i = 0; i < 10; i++)
int_array_push_back(&a, i);
for(i = 0; i < a.length; i++)
printf("a[%d] = %d\n", i, a.array[i]);
int_array_free(&a);
Of course, this is only for an array of ints. Since C doesn't have templates, you'd have to either put all of this code in a macro for each different type of array (or use a different preprocessor such as GNU m4). Or, you could use a generic array container that either used void* pointers (requiring all array elements to be malloc'ed) or opaque memory blobs, which would require a cast with every element access and a memcpy for every element get/set.
In any case, it's not pretty. Two-dimensional arrays are even uglier.
Instead of an array here, you could also use a linked list, The code is simpler, but the allocation is more frequent and may suffer from fragmentation.
As long as you don't plan to do much random access (Which is O(n) here), iteration is about as simple as a regular array.
typedef struct Line Line;
struct Line{
char text[LINE_MAX];
Line *next;
};
Line *mkline()
{
Line *l = malloc(sizeof(Line));
if(!l)
error();
return l;
}
main()
{
Line *lines = mkline();
Line *lp = lines;
while(fgets(lp->text, sizeof lp->text, stdin)!=NULL){
lp->next = mkline();
lp = lp->next;
}
lp->next = NULL;
}
If you are using C you will need to implement the resizing of the array yourself. C++ and the SDL has this done for you. It is called a vector. http://www.cplusplus.com/reference/stl/vector/
While a multidimensional array can solve this problem, a rectangular 2D array would not really be the natural C solution.
Here is a program that initially reads the file into a linked list, and then allocates a vector of pointers of the right size. Each individual character does then appear as array[line][col] but in fact each row is only as long as it needs to be. It's C99 except for <err.h>.
#include <err.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct strnode {
char *s;
struct strnode *next;
} strnode;
strnode *list_head;
strnode *list_last;
strnode *read1line(void) {
char space[1024];
if(fgets(space, sizeof space, stdin) == NULL)
return NULL;
strnode *node = malloc(sizeof(strnode));
if(node && (node->s = malloc(strlen(space) + 1))) {
strcpy(node->s, space);
node->next = NULL;
if (list_head == NULL)
list_head = node;
else
list_last->next = node;
list_last = node;
return node;
}
err(1, NULL);
}
int main(int ac, char **av) {
int n;
strnode *s;
for(n = 0; (s = read1line()) != NULL; ++n)
continue;
if(n > 0) {
int i;
strnode *b;
char **a = malloc(n * sizeof(char *));
printf("There were %d lines\n", n);
for(b = list_head, i = 0; b; b = b->next, ++i)
a[i] = b->s;
printf("Near the middle is: %s", a[n / 2]);
}
return 0;
}
You can use the malloc and realloc functions to dynamically allocate and resize an array of pointers to char, and each element of the array will point to a string read from the file (where that string's storage is also allocated dynamically). For simplicity's sake we'll assume that the maximum length of each line is less than M characters (counting the newline), so we don't have to do any dynamic resizing of individual lines.
You'll need to keep track of the array size manually each time you extend it. A common technique is to double the array size each time you extend, rather than extending by a fixed size; this minimizes the number of calls to realloc, which is potentially expensive. Of course that means you'll have to keep track of two quantities; the total size of the array and the number of elements currently read.
Example:
#define INITIAL_SIZE ... // some size large enough to cover most cases
char **loadFile(FILE *stream, size_t *linesRead)
{
size_t arraySize = 0;
char **lines = NULL;
char *nextLine = NULL;
*linesRead = 0;
lines = malloc(INITIAL_SIZE * sizeof *lines);
if (!lines)
{
fprintf(stderr, "Could not allocate array\n");
return NULL;
}
arraySize = INITIAL_SIZE;
/**
* Read the next input line from the stream. We're abstracting this
* out to keep the code simple.
*/
while ((nextLine = getNextLine(stream)))
{
if (arraySize <= *linesRead)
{
char **tmp = realloc(lines, arraysSize * 2 * sizeof *tmp);
if (tmp)
{
lines = tmp;
arraySize *= 2;
}
}
lines[(*linesRead)++] = nextLine;
)
return lines;
}

malloc() of struct array with varying size structs

How does one malloc an array of structs correctly if each struct contains an array of strings which vary in size?
So each struct might have a different size and would make it impossible to
realloc(numberOfStructs * sizeof(structName))
after
malloc(initialSize * sizeof(structName)
How does one allocate memory for this and keep track of what is going on?
If your structure has a char *, it takes up the size of one pointer. If it has a char[200], it takes up two hundred bytes.
I am making some guesses here, based on the information you have provided. The only reason I can see for wanting to realloc an array of structs is if you want to add more structs to that array. That's cool. There are plenty of reasons to want that kind of dynamic storage. The best way to handle it, especially if the structures are themselves dynamic, is to keep an array of pointers to these structures. Example:
1. Data structure:
typedef struct {
int numberOfStrings;
char ** strings;
}
stringHolder;
typedef struct {
int numberOfStructs;
stringHolder ** structs;
}
structList;
2. Managing dynamic arrays of strings:
void createNewStringHolder(stringHolder ** holder) {
(*holder) = malloc(sizeof(stringHolder));
(*holder)->numberOfStrings = 0;
(*holder)->strings = NULL;
}
void destroyStringHolder(stringHolder ** holder) {
// first, free each individual string
int stringIndex;
for (stringIndex = 0; stringIndex < (*holder)->numberOfStrings; stringIndex++)
{ free((*holder)->strings[stringIndex]); }
// next, free the strings[] array
free((*holder)->strings);
// finally, free the holder itself
free((*holder));
}
void addStringToHolder(stringHolder * holder, const char * string) {
int newStringCount = holder->numberOfStrings + 1;
char ** newStrings = realloc(holder->strings, newStringCount * sizeof(char *));
if (newStrings != NULL) {
holder->numberOfStrings = newStringCount;
holder->strings = newStrings;
newStrings[newStringCount - 1] = malloc((strlen(string) + 1) * sizeof(char));
strcpy(newStrings[newStringCount - 1], string);
}
}
3. Managing a dynamic array of structures:
void createNewStructList(structList ** list, int initialSize) {
// create a new list
(*list) = malloc(sizeof(structList));
// create a new list of struct pointers
(*list)->numberOfStructs = initialSize;
(*list)->structs = malloc(initialSize * sizeof(stringHolder *));
// initialize new structs
int structIndex;
for (structIndex = 0; structIndex < initialSize; structIndex++)
{ createNewStringHolder(&((*list)->structs[structIndex])); }
}
void destroyStructList(structList ** list) {
// destroy each struct in the list
int structIndex;
for (structIndex = 0; structIndex < (*list)->numberOfStructs; structIndex++)
{ destroyStringHolder(&((*list)->structs[structIndex])); }
// destroy the list itself
free((*list));
}
stringHolder * addNewStructToList(structList * list) {
int newStructCount = list->numberOfStructs + 1;
size_t newSize = newStructCount * sizeof(stringHolder *);
stringHolder ** newList = realloc(list->structs, newSize);
if (newList != NULL) {
list->numberOfStructs = newStructCount;
list->structs = newList;
createNewStringHolder(&(newList[newStructCount - 1]));
return newList[newStructCount - 1];
}
return NULL;
}
4. Main program:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main (int argc, char * argv[]) {
structList * allHolders;
createNewStructList(&allHolders, 10);
addStringToHolder(allHolders->structs[4], "The wind took it");
addStringToHolder(allHolders->structs[4], "Am I not merciful?");
addStringToHolder(allHolders->structs[7], "Aziz, Light!");
printf("%s\n", allHolders->structs[4]->strings[0]); // The wind took it
printf("%s\n", allHolders->structs[4]->strings[1]); // Am I not merciful?
printf("%s\n", allHolders->structs[7]->strings[0]); // Aziz, Light!
stringHolder * newHolder = addNewStructToList(allHolders);
addStringToHolder(newHolder, "You shall not pass!");
printf("%s\n", newHolder->strings[0]); // You shall not pass!
printf("%s\n", allHolders->structs[10]->strings[0]); // You shall not pass!
destroyStructList(&allHolders);
return 0;
}
You don't, generally. There are two reasons you might want to do this:
So that a single free() will release the entire block of memory.
To avoid internal memory fragmentation.
But unless you have an exceptional situation, neither are very compelling, because there is crippling drawback to this approach:
If you do this, then block[i] is meaningless. You have not allocated an array. There is no way to tell where your next struct starts without either examining the struct or having outside information about the size/position of your structs in the block.
It is not so clear how your struct type is declared. C99 has a special construct for such things, called flexible array member of a struct:
As a special case, the last element of
a structure with more than one named
member may have an incomplete array
type; this is called a flexible array
member.
You could do something like
typedef struct myString myString;
struct myString { size_t len; char c[]; };
You may then allocate such a beast with
size_t x = 35;
myString* s = malloc(sizeof(myString) + x);
s->len = x;
and reallocate it with
size_t y = 350;
{
myString* tmp = realloc(s, sizeof(myString) + y);
if (!tmp) abort(); // or whatever
tmp->len = y;
}
s = tmp;
To use this more comfortably you'd probably better wrap this into macros or inline functions.

Resources