Apologies if this seems like a duplicate question but I'd like some clarification on a previous question I found here regarding allocating heap memory using malloc for a struct containing a pointer. I have found various other questions regarding malloc and structs, but for some reason they all seem to involve people using typedef when defining the struct, I don't know if this changes the context of the question so I want to avoid confusion by asking a new question.
So the answers to this question seems to imply that with a struct such as:
struct Vector {
double *data;
size_t size;
};
When creating an instance we should allocate memory space for the struct itself:
struct Vector *retVal = malloc (sizeof (struct Vector));
AND the pointer to data inside the struct:
retVal->data = malloc (sz * sizeof (double));
Problem is I've been reading 'The ANSI C Programming Language' (second edition) by Brian Kernighan and Dannis Ritchie, it's quite an old book but I assumed it was good stuff. Unfortunately it doesn't go into malloc
in much detail. I then came across the following code on page 119 which is illustrating an example of how symbol table management (e.g. for the preprocessor) might work. It defines a struct (nlist) for a symbol and the text to replace the symbol with. nlists are stored in a static array (hashtab), using a simple hash function then a modulo array size of the hash to calculate the array index, so there is a pointer to the next nlist if there is a collision:
struct nlist { /* table entry: */
struct nlist *next; /* next entry in chain */
char *name; /* defined name */
char *defn; /* replacement text */
};
There is then an install function which is used to add a new nlist to hashtab:
struct nlist *lookup(char *);
char *strdup(char *);
/* install: put (name, defn) in hashtab */
struct nlist *install(char *name, char *defn)
{
struct nlist *np;
unsigned hashval;
if ((np = lookup(name)) == NULL) { /* not found */
np = (struct nlist *) malloc(sizeof(*np));
if (np == NULL || (np->name = strdup(name)) == NULL)
return NULL;
hashval = hash(name);
np->next = hashtab[hashval];
hashtab[hashval] = np;
} else /* already there */
free((void *) np->defn); /*free previous defn */
if ((np->defn = strdup(defn)) == NULL)
return NULL;
return np;
}
This is the point at which I started to weep and rock backwards and forwards, drooling as my brain melted out of my ears. There doesn't appear to be any malloc
action going on for the pointers to next
, name
or defn
in the nlist
struct. Is this right or wrong?
Thanks.
PS the lookup function is:
/* lookup: look for s in hashtab */
struct nlist *lookup(char *s)
{
struct nlist *np;
for (np = hashtab[hash(s)]; np != NULL; np = np->next)
if (strcmp(s, np->name) == 0)
return np; /* found */
return NULL; /* not found */
}