Thread: Multi-dimensonal array (char **) bug....

  1. #1
    Registered User
    Join Date
    Sep 2005
    Posts
    2

    Unhappy Multi-dimensonal array (char **) bug....

    Im currently working on a file searching function that recursively scans for files matching a keyword, and then returns a list containing all the full paths to files matching the pattern.

    The problem is (as far as I can tell) a single line (#54);
    Code:
    match_list[match_list_len] = match;
    , where match_list is type "char **" and match is a string.

    If anyone is interested, here's the relevant code
    Code:
    /* -- Universal directory scanning function -- */
    /* returns a list to matching files or NULL if non exist */
    /* keyword = keyword to look for */
    /* mode = filemode needed (F_OK / R_OK / W_OK) */
    /* length = length of list returned */
    /* scan_subdir = (true or false) wether or not to scan subdirectories */
    char **ScanDirectory(char scan_directory[], char *keyword, int mode, int depth)
    {
        printf("\nScanning %s ...\n", scan_directory);
        printf("access(scan_directory, R_OK) = %d\n", access(scan_directory, R_OK)); 
        if(depth < 0) 									/* Maximum depth reached */
        {
            printf("maximum depth reached\n");
            return NULL;
        }
        if(access(scan_directory, F_OK) != 0 || access(scan_directory, R_OK) != 0) 		/* Check for directory existence and read access */
        {
            printf("%s we dont have read access or directory does not exist!\n", scan_directory);
            return NULL;
        }
        printf("depth = %d\n", depth);
        DIR *dp;
        struct dirent *ep;
        char **match_list;									/* List of files matching keyword */
        int match_list_len = -1;								/* Current length of char **match */
        
        dp = opendir(scan_directory);							/* Open the directory to be scanned */
        if(dp != NULL)
        {
            int d_namesize;
            while (ep = readdir(dp))							/* Scan the directory */
            {
                printf("ep->d_name = %s\n", ep->d_name);
                printf("match_list_len = %d\n", match_list_len);
                if(strstr(ep->d_name, keyword) != NULL)					/* Keyword Match */
                {
                    char match[STD_BUF_SIZE * 2];
                    snprintf(match, STD_BUF_SIZE * 2, "%s/%s", scan_directory, ep->d_name);
                    printf("match = %s\n", match);
                    if(access(match, mode) == 0)						/* Keyword Permission Check */
                    {
                        printf("\nMatch found! %s\n", match);
                        match_list_len++;
                        printf("match_list_len = %d\n", match_list_len);
                        match_list[match_list_len] = match;					/* NOT WORKING */
                        printf("match_list[0] = %s\n", match_list[0]);			/* Increment length */
                        printf("1\n");
                        printf("match_list[%d] = %s\n", match_list_len, match_list[match_list_len]);
                    }
                    else printf("Not Enough Access :(\n");
                }
                d_namesize = strlen((char *)ep->d_name);
                if(depth > 0 && ep->d_type == DT_DIR && ep->d_name[d_namesize - 1] != '.')
                {										/* Scan the subdirectory */
                    char sub_dir[512], **result;
                    strcpy(sub_dir, scan_directory);
                    if(scan_directory != "/") strcat(sub_dir, "/");
                    strcat(sub_dir, ep->d_name);
                    result = ScanDirectory(sub_dir, keyword, mode, depth - 1); 
                    if(result != NULL)
                    {
                        int copycount;
                        printf("\nCopying Subdirectory list....\n");
                        for(copycount = 0; result[copycount] != NULL; copycount++) 
                        {
                            printf("result[%d] = %s\n", copycount, result[copycount]);
                            match_list[match_list_len + copycount] = result[copycount];	/* Copy the results into our list */
                            printf("match_list[%d] = %s\n", copycount + match_list_len, match_list[match_list_len + copycount]);
                        }
                    }
                    else printf("subdir scan found nothing :(\n");
                }
            }
        }
        else
        {
            printf("Directory %s is empty :(\n", scan_directory);
            closedir(dp);									/* Directory is empty */
            match_list_len = -1;
            return NULL;									/* Failure */
        }
        closedir(dp);
        printf("\nmatch_list_len = %d\n", match_list_len);
        if(match_list_len > -1)								/* Ecleast 1 match */
        {
            int printcount;
            printf("Verifying...\n");
            for(printcount = 0; printcount < match_list_len; printcount++)
            {
                printf("match_list[%d] = %s\n", printcount, match_list[printcount]);
            }
            printf(" ### ScanDirectory Success :) ###\n");
            return match_list;								/* Success */
        }
    }
    Im running Mac OS X (aka BSD), and the code compiles fine, but 'Bus Error's when it reaches the line in question. If anyone could post any feedback that would be very helpful.

  2. #2
    Registered Luser cwr's Avatar
    Join Date
    Jul 2005
    Location
    Sydney, Australia
    Posts
    869
    When you delcare something char **, you are not declaring an array, you are declaring a pointer to a pointer to a char. The only space allocated is for one single pointer. To use it like you are using it, you need to allocate some memory using malloc. First, you need to malloc space for N char *'s, then for each string entry, you need to malloc space for your array of chars.

    Because you don't know how many to malloc for inadvance, look into realloc.

    Have a look at this FAQ entry also.

  3. #3
    Registered User
    Join Date
    Sep 2005
    Posts
    2

    Smile

    Thanks for the quick reply

  4. #4
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    faq.cprogramming.com has some code to read in files from a directory.
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Sorting Linked Lists
    By DKING89 in forum C Programming
    Replies: 6
    Last Post: 04-09-2008, 07:36 AM
  2. Program Crashing
    By Pressure in forum C Programming
    Replies: 3
    Last Post: 04-18-2005, 10:28 PM
  3. String sorthing, file opening and saving.
    By j0hnb in forum C Programming
    Replies: 9
    Last Post: 01-23-2003, 01:18 AM
  4. simulate Grep command in Unix using C
    By laxmi in forum C Programming
    Replies: 6
    Last Post: 05-10-2002, 04:10 PM