#1
  1. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jan 2012
    Posts
    6
    Rep Power
    0

    Return Structure to main program - some values not returned


    Hi there,
    I have a simple question. This code is returning pointer to a structure from function to main program. All fields from structure that are strings are returned well but integers are not. Cannot find out why....
    Can someone experienced check on this code ?

    Thanks.

    Code:
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <dirent.h>
    #include <string.h>
    #include <stdio.h>
    #include <stdlib.h>
    #define PATH_LENGTH 256
    #define SOURCE "C:\\temp\\test"
    ////////////////////////////
    struct dirent *pDirEntry;  /* pointer to a directory entry */
    DIR *pDir;  /* pointer to the directory */
    struct stat Stat;
    char Path[PATH_LENGTH];
    ////////////////////////////
    typedef struct dirsAndFiles
    {
    char **dirs;
    char **files;
    int dirs_numb;
    int files_numb;
    } dirsAndFiles_t;
    /////////////////////////////////////////
    //Function that resolves dirs and files//
    /////////////////////////////////////////
    dirsAndFiles_t * ResolveDirsAndFiles(char * source_path)
    {
    dirsAndFiles_t *pS_push = malloc(sizeof(struct dirsAndFiles));
    dirsAndFiles_t S_push = *pS_push;
    S_push.dirs_numb=0;
    S_push.files_numb=0;
    //allocate memory for array of strings
    pS_push->dirs=malloc(256*sizeof(char *));
    pDir = opendir(source_path);
       while (1)
        {
          pDirEntry = readdir(pDir);
          if (pDirEntry == 0) break;  // reached end of directory entries
          // process file (other than . and ..)
          if (strcmp(pDirEntry->d_name,".") != 0 &&
              strcmp(pDirEntry->d_name,"..") != 0)
              {
                // print just name
                printf("%s",pDirEntry->d_name);
                // apsolute path
                Path[0] = 0;
                strcat(Path,source_path);
                strcat(Path,"\\");
                strcat(Path,pDirEntry->d_name);
                if(stat(Path,&Stat)!=NULL) break;
                if (S_ISDIR(Stat.st_mode)) //it is dir
                    {
                        //allocate memory
                        pS_push->dirs[S_push.dirs_numb]=malloc((strlen(Path))*sizeof(char));
                        //copy path to structure
                        strcpy(pS_push->dirs[S_push.dirs_numb],Path);
                        //control printing
                        printf("\n%s",pS_push->dirs[S_push.dirs_numb]);
                        printf("--%d\n",S_push.dirs_numb);
                        S_push.dirs_numb++;
                    }
                 else //it is file
                    {
                        //allocate memory
                        pS_push->files[S_push.files_numb]=malloc((strlen(Path))*sizeof(char));
                        //copy path to structure
                        strcpy(pS_push->files[S_push.files_numb],Path);
                        //control printing
                        printf("\n%s",pS_push->files[S_push.files_numb]);
                        printf("--%d\n",S_push.files_numb);
                        S_push.files_numb++;
                    }
                printf("\n");
                }
       }
    closedir(source_path);
    //free memory ....
    return pS_push;
    }
    
    int main()
    {
    //define structure and allocate memory
    dirsAndFiles_t *pS_pull = malloc(sizeof(struct dirsAndFiles));
    dirsAndFiles_t S_pull=*pS_pull;
    //call function and result put to structure
    pS_pull=ResolveDirsAndFiles(SOURCE);
    
    //printf("%s",S_pull.dirs[0]);
    //work with result that you now have in structure
    int i=0;
    int j=0;
    //print number of directories and print dir paths
    printf("Total dirs count = %d\n",S_pull.dirs_numb);
    while(i<3) //until I resolve problem with pS_pull->dirs_numb
    {
    printf("%s\n",pS_pull->dirs[i]);
    i++;
    }
    //print number of files and print file paths
    printf("\nTotal files count = %d\n",S_pull.files_numb);
    while(j<1) //until I resolve ....
    {
    printf("%s\n",pS_pull->files[j]);
    j++;
    }
    //free memory ...
    return 0;
    }
  2. #2
  3. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jan 2013
    Posts
    159
    Rep Power
    19
    You may want to look at the errors my compiler generated from your code:

    main.c|25|warning: no previous declaration for ‘ResolveDirsAndFiles’ [-Wmissing-declarations]|
    main.c||In function ‘ResolveDirsAndFiles’:|
    main.c|49|error: comparison between pointer and integer|
    main.c|75|error: passing argument 1 of ‘closedir’ from incompatible pointer type|
    /usr/include/dirent.h|151|note: expected ‘struct DIR *’ but argument is of type ‘char *’|
    ||=== Build finished: 3 errors, 1 warnings ===|
    Jim
  4. #3
  5. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jan 2012
    Posts
    6
    Rep Power
    0
    Hi Jim,

    Can you try now?

    I have corrected lines 49 and 75, but when debug I have an Segmentation Fault that still remains on line 65 which, by the way, has the same structure as line 54 which seams OK.

    If not debug, but execute I have "return 0" with starting problem that I have explained in first post.

    [EDIT] I don;t have an error on line 25. Can it be compiler related ? I am using GNU GCC Compiler that comes with CodeBlocks.

    Here is partially corrected code again:
    Code:
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <dirent.h>
    #include <string.h>
    #include <stdio.h>
    #include <stdlib.h>
    #define PATH_LENGTH 256
    #define SOURCE "C:\\temp\\test"
    ////////////////////////////
    struct dirent *pDirEntry;  /* pointer to a directory entry */
    DIR *pDir;  /* pointer to the directory */
    struct stat Stat;
    char Path[PATH_LENGTH];
    ////////////////////////////
    typedef struct dirsAndFiles
    {
    char **dirs;
    char **files;
    int dirs_numb;
    int files_numb;
    } dirsAndFiles_t;
    /////////////////////////////////////////
    //Function that resolves dirs and files//
    /////////////////////////////////////////
    dirsAndFiles_t * ResolveDirsAndFiles(char * source_path)
    {
    dirsAndFiles_t *pS_push = malloc(sizeof(struct dirsAndFiles));
    dirsAndFiles_t S_push = *pS_push;
    S_push.dirs_numb=0;
    S_push.files_numb=0;
    //allocate memory for array of strings
    pS_push->dirs=malloc(256*sizeof(char *));
    pDir = opendir(source_path);
       while (1)
        {
          pDirEntry = readdir(pDir);
          if (pDirEntry == 0) break;  // reached end of directory entries
          // process file (other than . and ..)
          if (strcmp(pDirEntry->d_name,".") != 0 &&
              strcmp(pDirEntry->d_name,"..") != 0)
              {
                // print just name
                printf("%s",pDirEntry->d_name);
                // apsolute path
                Path[0] = 0;
                strcat(Path,source_path);
                strcat(Path,"\\");
                strcat(Path,pDirEntry->d_name);
                //if(stat(Path,&Stat)!='NULL') break;
                stat(Path,&Stat);
                if (S_ISDIR(Stat.st_mode)) //it is dir
                    {
                        //allocate memory
                        pS_push->dirs[S_push.dirs_numb]=malloc((strlen(Path))*sizeof(char));
                        //copy path to structure
                        strcpy(pS_push->dirs[S_push.dirs_numb],Path);
                        //control printing
                        printf("\n%s",pS_push->dirs[S_push.dirs_numb]);
                        printf("--%d\n",S_push.dirs_numb);
                        S_push.dirs_numb++;
                    }
                 else //it is file
                    {
                        //allocate memory
                        pS_push->files[S_push.files_numb]=malloc((strlen(Path))*sizeof(char));
                        //copy path to structure
                        strcpy(pS_push->files[S_push.files_numb],Path);
                        //control printing
                        printf("\n%s",pS_push->files[S_push.files_numb]);
                        printf("--%d\n",S_push.files_numb);
                        S_push.files_numb++;
                    }
                printf("\n");
                }
       }
    closedir(pDir);
    //free memory ....
    return pS_push;
    }
    
    int main()
    {
    //define structure and allocate memory
    dirsAndFiles_t *pS_pull = malloc(sizeof(struct dirsAndFiles));
    dirsAndFiles_t S_pull=*pS_pull;
    //call function and result put to structure
    pS_pull=ResolveDirsAndFiles(SOURCE);
    
    //printf("%s",S_pull.dirs[0]);
    //work with result that you now have in structure
    int i=0;
    int j=0;
    //print number of directories and print dir paths
    printf("Total dirs count = %d\n",S_pull.dirs_numb);
    while(i<3) //until I resolve problem with pS_pull->dirs_numb
    {
    printf("%s\n",pS_pull->dirs[i]);
    i++;
    }
    //print number of files and print file paths
    printf("\nTotal files count = %d\n",S_pull.files_numb);
    while(j<1) //until I resolve ....
    {
    printf("%s\n",pS_pull->files[j]);
    j++;
    }
    //free memory ...
    return 0;
    }
  6. #4
  7. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,172
    Rep Power
    2222
    You dirty dog, you! You're doing this under Windows, not Linux! jimblumberg was using the gcc on Linux.

    I just tried to compile it with MinGW gcc and got this:
    C:TEST>gcc -Wall olafson.c
    olafson.c: In function `main':
    olafson.c:91: parse error before `int'
    olafson.c:95: `i' undeclared (first use in this function)
    olafson.c:95: (Each undeclared identifier is reported only once
    olafson.c:95: for each function it appears in.)
    olafson.c:102: `j' undeclared (first use in this function)

    C:TEST>
    What are you compiling this as? C? Or C99? If the latter, then why didn't you tell us? Like you didn't bother to tell us what OS you were using. Obviously, we need to know these things if we are going to be able to try to help you. Or feel inclined to.

    After moving the declarations of i and j back where they belong and figuring out which library to link in for the dirent functions, it compiled. But my debugger is in Visual Studio; I do have gdb, but I've never used it. At least I solved the compiler mystery.
  8. #5
  9. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jan 2013
    Posts
    159
    Rep Power
    19
    When I compiled your code it compiles without errors.

    Part of your problem is your use of all those global variables makes it difficult to debug your program. But you really need to test the return values of your opendir() function, if this function returns NULL you shouldn't be calling readdir() with this NULL pointer.

    Also you should really be using the Linux path separator (/) instead of the Windows separator (\) since you are using the MSYS library to emulate Linux/Unix system functionality on Windows.

    Once you stop using the global variables you should be able to run the program in your debugger and find the problem. And remember most of the functions you are using return values that should be checked for validity and actions taken if they fail.

    Oh, and yes I'm using Linux and all your "DOS" path separators mean I can't run your program without getting segmentation faults because of NULL pointer dereferencing because the paths don't exist on my machine. Also note that I'm using the -std=C11 switch on my compiler.

    Jim

IMN logo majestic logo threadwatch logo seochat tools logo