free problem

Discussion in 'Mac Programming' started by jamesapp, Jun 17, 2008.

  1. macrumors 6502a

    #include <stdio.h>
    #include <ctype.h>
    #include <string.h>
    struct tnode {  /* the tree nod: */
       char *word;  /* points to the text */
       int count;  /* number of occurences */
       struct tnode *left;  /* left child */
       struct tnode *right;  /* right child */
    #define MAXWORD 100
    struct tnode *addtree(struct tnode *, char *);
    void treeprint(struct tnode *);
    int getword(char *, int);
    /*word frequency count */
      struct tnode *root;
      char word[MAXWORD];
      root = NULL;
      while (getword(word, MAXWORD) != EOF)
          if (isalpha(word[0]))
              root = addtree(root, word);
      return 0;
    struct tnode *talloc(void);
    /* addtree: add a node with w, at or below p */
    struct tnode *addtree(struct tnode *p, char *w)
      int cond;
      if (p == NULL) {  /* a new word has arrived */
          p = talloc();  /* make a new node */
          p->word = strdup(w);
          p->count = 1;
          p->left = p->right = NULL;
      } else if ((cond = strcmp(w, p->word)) == 0)
          p->count++;  /* repeated word */
      else if (cond < 0)  /* less than into left subtree */
          p->left = addtree(p->left, w);
      else     /* greater than into right subtree */
          p->right = addtree(p->right, w);
      return p;
    /* treeprint: in-order print of tree p */
    void treeprint(struct tnode *p)
      if (p != NULL) {
          printf("%4d %s\n", p->count, p->word);
    /* getword: get next word or characters from input */
    int getword(char *word, int lim)
      int c, getch(void);
      void ungetch(int);
      char *w = word;
      while (isspace(c = getch()))
      if (c != EOF)
          *w++ = c;
      if (!isalpha(c)) {
          *w = '\0';
          return c;
      for ( ; --lim > 0; w++)
          if (!isalnum(*w = getch())) {
       *w = '\0';
       return word[0];
    #define BUFSIZE 100
    char buf[BUFSIZE];  /* buffer for ungetch */
    int bufp = 0;  /* next free position in buf */
    int getch(void)  /* get a (possibly pushed back) character */
      return (bufp > 0) ? buf[--bufp] : getchar();
    void ungetch(int c)  /* push character back on input */
      if (bufp >= BUFSIZE)
          printf("ungetch: too many characters\n");
          buf[bufp++] = c;
    #include <stdlib.h>
    /* talloc: make a tnode */
    struct tnode *talloc(void)
      return (struct tnode *) malloc(sizeof(struct tnode));
    the following program is from a book on the c programming language.
    from the book: "Storage obtained by calling malloc may be freed for re-use by calling free" just wondering exactly how to free malloc? Any information on the process of using free, would be appreciated.
  2. macrumors 603


  3. macrumors 68040

    To make a long story short, any memory that you allocate using any of the alloc functions (malloc, calloc, etc.) should also be free'd by you or your program could have a memory leak. This means that you need to make sure to always have at least one pointer available to any memory that you have malloc'ed so that you can free that memory when you're done with it.
  4. macrumors 6502a

    i see in the code from the book:
    struct tnode *talloc(void);
    i also see:
    /* talloc: make a tnode */
    struct tnode *talloc(void)
      return (struct tnode *) malloc(sizeof(struct tnode));
    from the above code snippets, does *talloc(void)
    mean that talloc(void) is a pointer to tnode?
    and so i would use like:
  5. macrumors 68040


    I'm not sure what level of knowledge you have yet, so I'll try to cover this as briefly as possible and can expand if needed.

    talloc is a function. Its return type is a pointer to a tnode structure. Every time you call talloc, a malloc is performed, and the pointer returned will need to have free called on it.


    void myfunction(int numToGrab) {
      int counter=0;
      tnode *list = null;
      list = (tnode *)malloc(sizeof(tnode *)*numToGrab);
      for(counter = 0; counter < numToGrab; counter++){
        list[counter] = talloc();
      //Do some work with all of those tnodes
      for(counter = 0; counter < numToGrab; counter++){
        free((void *)list[counter]);
      free((void *)list);
    In the example i malloc'd my own list to use to store tnode pointers. I then called talloc the number of times specified (note, i didn't make sure numToGrab was positive, etc. so this could cause an overflow situation). I put a comment where you could do some work with all of those tnodes you allocated with talloc. I then free'd EACH of those tnodes first, THEN free'd the list i had allocated.

    If I free'd my list first, I wouldn't have assured access to the tnode *s that I needed to free, so sometimes the order of freeing, not just that you do it, is important too.

  6. macrumors 6502

    I find that most of my problems are free.
  7. macrumors regular

    Just to be clear, the first block is the declaration of the function 'talloc'. It tells the compiler that you are promising to define the function at some later time. The second block is where you fulfill your promise to the compiler by defining the 'talloc' function.
  8. macrumors 6502a

    Not sure how much I know, but it the C / Objective - C book I'm reading it just says to add the

    [objectName free];

    command to the end of the program.

    Also, if you turn on garbage collection, doesn't this do it for you in Leopard?

    Project -> Project Settings -> 'Build' tab -> search for 'garbage'
  9. macrumors 68040

    The OP appears to be using straight up C, so the Objective-C stuff doesn't apply.
  10. macrumors 6502a

    Oh yeah, I see now from the lack of square brackets ;)
  11. macrumors regular

    If the OP is still struggling with this, the solution lies in the fact that your 'alloc'ated blocks of memory are being added to a binary tree, which (theoretically) gives you a complete data structure containing pointers to all of the memory blocks you've allocated. When it's time to release all of those blocks, you'll want to traverse your binary tree (much in the same way you traverse the tree when adding new elements to it) and free each block. I'll not reveal the complete solution and leave the implementation details as an exercise.

Share This Page