Thread: realloc() questions

  1. #1
    Registered User
    Join Date
    Nov 2006
    Posts
    176

    realloc() questions

    I'm making a program that basically takes as input a path and can output the total size of all files/directories inside it. the program recusivly scans through the directory givin and sums up the size of all files in all subfolders. heres the directory structure I've made

    Code:
    struct directory {
            char *name;
            int size;
            int nfiles;
            int ndirs;
            struct directory *parent;
            struct directory **dlist;
            File **flist;
    };
    in order to put a new directory in **dlist I use this function, which should increase the size of the **dlist member and add the new directory to the list

    Code:
    int dir_add_dir(struct directory *d, struct directory *new)
    {
            int ndirs;
            struct directory **temp;
    
            ndirs = d->ndirs;
    
            if ((temp = (struct directory **)realloc(d->dlist, sizeof(struct directory *) * (ndirs + 1))) == NULL)
            {
                    printf("Memory Error\n");
                    return -1;
            }
    
            d->dlist = temp;
            d->dlist[ndirs] = new;
    
            d->size += new->size;
    
            d->ndirs++;
    
            return 1;
    }
    d being the parent and new being the directory to add.
    I keep getting seg faults though, and when I run it with valgrind it is complaining about the realloc.

    am I going about this wrong...or just using realloc wrong. There is no way to tell how many elements will have to go in the list, so it must be updated dynamically.
    Last edited by sl4nted; 11-08-2006 at 12:40 AM.

  2. #2
    Registered User
    Join Date
    Mar 2006
    Posts
    725
    You're really doing it bad. realloc() may need to copy the entire array over to the new, larger array in case of memory fragmentation. You should be increasing at a fixed rate, say double the array size everytime you fill it. Keep two variables: a size variable for the number of entries in the array, and a capacity vaariable for the maximum number of entries storable before reallocation is required.

    Minor issues:
    - Don't cast pointers. (See FAQ)
    - Extra local ndirs is redundant and occurances can be replaced with d->ndirs without any problems.
    - You don't seem to update new->parent. (If I get the usage of parent correctly.)

    Anyway, this should do it (not really tested):
    Code:
    struct directory {
            char *name;
            int size;
            int nfiles;
            int ndirs; /* the used size of the array */
            int cdirs; /* the pre-allocated size */
            struct directory *parent;
            struct directory **dlist;
    };
    
    int dir_add_dir(struct directory *d, struct directory *new)
    {
        struct directory **temp;
        /* if array is full */
        if(d -> ndirs == d -> cdirs)
        {
            if((temp = realloc(d -> dlist, sizeof(struct directory*) * d -> cdirs * 2)) == NULL)
            {
                printf("Memory Error\n");
                return 0;
            }
            d -> dlist = temp;
            d -> cdirs *= 2; /* double capacity of array */
        }
        d -> dlist[d -> ndirs] = new;
        ++d -> ndirs; /* add one to the used size NOT the actual array size */
        d -> size += new -> size;
        new -> parent = d;
        return 1;
    }
    You might want to check out en.wikipedia.org/wiki/Dynamic_array. If you are also deleting directory entries as well as adding them, you could also add a check to halve the size of the arrays if less than say 1/2 of the array is in use.
    Last edited by jafet; 11-08-2006 at 05:43 AM.
    Code:
    #include <stdio.h>
    
    void J(char*a){int f,i=0,c='1';for(;a[i]!='0';++i)if(i==81){
    puts(a);return;}for(;c<='9';++c){for(f=0;f<9;++f)if(a[i-i%27+i%9
    /3*3+f/3*9+f%3]==c||a[i%9+f*9]==c||a[i-i%9+f]==c)goto e;a[i]=c;J(a);a[i]
    ='0';e:;}}int main(int c,char**v){int t=0;if(c>1){for(;v[1][
    t];++t);if(t==81){J(v[1]);return 0;}}puts("sudoku [0-9]{81}");return 1;}

  3. #3
    Registered User ssharish2005's Avatar
    Join Date
    Sep 2005
    Location
    Cambridge, UK
    Posts
    1,732
    why dont u make as a linked list. Do that when u find a new directory inside a directory, create a node of type Directory and link along with the dlink rather than realloc. which is quite more dynamic.

    ssharish2005

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. did i understood right this explantion of realloc..
    By transgalactic2 in forum C Programming
    Replies: 3
    Last Post: 10-24-2008, 07:26 AM
  2. A very long list of questions... maybe to long...
    By Ravens'sWrath in forum C Programming
    Replies: 16
    Last Post: 05-16-2007, 05:36 AM
  3. questions about realloc()
    By TalosChen in forum C Programming
    Replies: 11
    Last Post: 05-10-2006, 08:24 PM
  4. using realloc
    By bobthebullet990 in forum C Programming
    Replies: 14
    Last Post: 12-06-2005, 05:00 PM
  5. Trivial questions - what to do?
    By Aerie in forum A Brief History of Cprogramming.com
    Replies: 23
    Last Post: 12-26-2004, 09:44 AM