0

After more than 10 years of having the luxury of using garbage collected languages, I am returning to C99 and obviously I am having difficulties with memory management.

I have a linked list consisting of stack items and a type Stack which points to the address of the first element of this list.

This is my code so far:

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

typedef struct StackItem
{
    int head;
    struct StackItem* next;
} StackItem;

typedef StackItem** Stack;

StackItem* makeStackItem (int head)
{
    StackItem* a = (StackItem*) malloc (sizeof (StackItem) );
    a->head = head;
    a->next = (StackItem*) 0;
    return a;
}

Stack makeStack ()
{
    Stack stack = (Stack) malloc (sizeof (StackItem*) );
    *stack = (StackItem*) 0;
    return stack;
}

void pushStack (StackItem* item, Stack stack)
{
    item->next = *stack;
    *stack = item;
}

void freeStack (Stack stack)
{
    StackItem* current = *stack;
    StackItem* next;
    while (current != 0)
    {
        next = current->next;
        free (current);
        current = next;
    }
    free (stack);
}

int main ()
{
    Stack stack = makeStack ();
    for (int i = 0; i < 10; i++)
        pushStack (makeStackItem (i), stack);
    printf ("Here be dragons.\n");
    freeStack (stack);
    return 0;
}

My questions are:

  1. Are the first lines of makeStack and makeStackItem sensible and necessary?

  2. Is the last line of freeStack sensible and necessary?

  3. Once main returns, have I freed all the memory previously allocated?

  4. How can I see whether I have memory leaks or not?

Thank you very much in advance.

Hyperboreus
  • 31,997
  • 9
  • 47
  • 87
  • 3
    on your 4th question I'd advise checking out [valgrind](http://valgrind.org/) – Natan Streppel Nov 19 '13 at 19:45
  • 2
    casting malloc is discouraged. I personally hate hiding indirections in typedef's, it makes the code less readable ( typedef StackItem** Stack; ) – Charlie Burns Nov 19 '13 at 19:49
  • Charlie beat me to it, but here's why - http://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc – Leeor Nov 19 '13 at 19:50
  • In type declarations, asterisks bind to the *right*, and should be spaced to emphasize this: `StackItem *stack`, *not* `StackItem* stack`. (Many people say just the opposite. They are wrong.) – zwol Nov 19 '13 at 19:52
  • Thank you everybody. I will look into this valgrind. – Hyperboreus Nov 19 '13 at 20:16

1 Answers1

1

Are the first lines of makeStack and makeStackItem sensible and necessary? yes except for the casting malloc issue

Is the last line of freeStack sensible and necessary? yes

Once main returns, have I freed all the memory previously allocated? yes

How can I see whether I have memory leaks or not? use valgrind

I would toss the casts of 0 too.
Charlie Burns
  • 6,994
  • 20
  • 29
  • Just to get you right: Basically replace `(sometype*) malloc ()` with `malloc ()` and `(sometype*) 0` with `0`? – Hyperboreus Nov 19 '13 at 20:08
  • Yes, that's what I would suggest. – Charlie Burns Nov 19 '13 at 20:15
  • `(sometype*)0` is necessary when (and *only* when) you are passing a null pointer as one of the anonymous arguments to a variadic or unprototyped function. In that solitary context, a bare `0` does not convert to a null pointer when you want it to. The only time you are ever likely to encounter this issue is with the [`execl`](http://linux.die.net/man/3/execl) family, whose last argument must always be `(char *)0`. Note also that using `NULL` *does not* get you out of needing the explicit cast in this context, because `#define NULL 0` is a legitimate thing for `` to do. – zwol Nov 19 '13 at 22:18
  • @Zack is that because of when sizeof(int) != sizeof(int *) ? – Charlie Burns Nov 19 '13 at 22:19
  • Yes, plus other more exotic possibilities, such as the CPU making a distinction between "address" and "data" registers and the ABI requiring pointer arguments to go in the former (M68K most famously; still a live possibility in the modern day), or the bit pattern for a null pointer not being all-bits-zero (very unlikely to come up nowadays; dim memory that some of the Burroughs minis did this, not sure) – zwol Nov 19 '13 at 22:26