Thread: How to access members of refered array?

  1. #1
    Registered User
    Join Date
    Sep 2014
    Posts
    235

    Question How to access members of refered array?

    Can you help to make this working?

    files.c
    Code:
    #include "include/types.h"
    #include "include/gaussian.h"
    #include <stdio.h>
    #include <stdlib.h>
    #include <stdbool.h>
    
    #include <dirent.h>
    #include <string.h> // strcmp, strtok
    #include <sys/types.h> // mkdir
    #include <sys/stat.h> // mkdir
    
    int makeConfig(char ** path)
    {
        char configFile [12] = "kernels.cfg";
        DIR *dir; struct dirent *ent;
        int count = -1;
    
        if ( ( dir = opendir (*path) ) != NULL)
        {
        char ch;
        FILE* f;
        FILE* f2;
        f = fopen(configFile, "r");
        if( f != NULL ) // if config already exists, backup
            {
            f2 = fopen("kernels.bak", "w");
            while( ( ch = fgetc(f) ) != EOF )
                fputc(ch, f2);
            fclose(f);
            fclose(f2);
            }
        // write new file
        f = fopen(configFile, "w");
            if( f == NULL )
                perror("Cannot write to file kernels.cfg");
    
    
        int ckey = 0;
        size_t len;
    
        while ((ent = readdir (dir)) != NULL)
            {
                if ( ckey<2 && ( strcmp(".",ent->d_name) == 0 ||  strcmp("..",ent->d_name) == 0 )  )
                    { ckey++; continue; }
    
                // backup ent->d_name because chTmp2 is changed by strtok
                len = strlen(ent->d_name);
                // char * dot = strchr( ent->d_name, '.' );
                if ( len >4 )
                    {
                    char name[64];
                    char * pName = ent->d_name;
                    char * ext;
                    ext = pName + len - 3;
                    memcpy( name, ent->d_name, len-3 );
                    if ( 0 == strcmp( ".",  name) )
                        {
                        printf("Incorrect kernel source name. File name %s, must not contain dots, but must have .cl extension.\n",ent->d_name);
                        }
                        else
                        {
                        name[len-3]='\0';
                        fprintf(f, "%s\n", name);
                        printf (".'%s'\n", ent->d_name);
                        }
                    }
                    else
                    {
                     printf("Incorrect kernel source name. File name %s too short.\n",ent->d_name);
                    }
            }
            closedir (dir); fclose(f);
        }
        else
        {
            /* could not open directory */
            char error [255];
            sprintf(error, "Directory not found: %s", *path);
            perror (error);
            return -1;
        }
    return count;
    }
    
    
    int readConfig(char ** path, FILES ** files )
    {
        char configFile [12] = "kernels.cfg";
        DIR *dir;
    
        if ( ( dir = opendir (*path) ) == NULL)
            {
                perror("directory of binary kernels not found");
                return -2;
            }
            else
                closedir(dir);
    
        FILE* f;
        f = fopen(configFile, "r");
        if( f == NULL ) // if config already exists, backup
            {
            perror("Config file kernels.cfg not found. Run the program with -install argument.");
            return -3;
            }
    
        int ch; int c = 0; int prevc = 0; int count = 0;
        char name[64];
        while ((ch=fgetc(f)) != EOF )
        {
           name[c]=ch;
           c++;
           if (ch == '\n' && c-prevc>1 )
               {
               files[count]->name=malloc(64);
               files[count]->filename=malloc(64);
               // strncpy(files[count].name, name, 64);
               strcpy(files[count]->name,name);
               files[count]->name[c-prevc-1]='\0'; // remove linefeed \n
               strcpy(files[count]->filename,name);
             //  files[count].filename[c-prevc+1]='\0';
               files[count]->name[c-prevc+4]='\0';
               strcat(files[count]->filename,".bin");
               count++;
               prevc=c;
               }
        }
    return count;
    }
    types.c
    Code:
    #include <stdbool.h>
    
    typedef struct  {
      char * name;
      char * filename;
    } FILES;
    main.c
    Code:
    #include "include/types.h"
    #include "include/gaussian.h"
    #include "include/args.h"
    #include "include/files.h"
    #include "refu/Time/rfc_timer.h"
    #include <stdio.h>
    
    int main ( int argc, char *argv[] )
    {
        char * path = "kernels";; // used as needed
        FILES files[256];
        int count;
    count = readConfig(&path, &files));
    After calling readConfig(&path, &files));
    I need to access the members .name and .filename to allocate memory and copy strings in there.

    Code:
    files[count]->name=malloc(64);
    files[count]->filename=malloc(64);
    SIGSEGV error
    How to make the reference working?

  2. #2
    Registered User
    Join Date
    Jun 2011
    Posts
    4,513
    Your "readConfig()" function expects a pointer to a pointer as its second argument, but you're trying to pass a pointer to an array. Arrays and pointers are not the same thing (See here: Question 6.2).

    Your compiler should be warning you about this. Honestly, there is a lot of code written in that function based around an incorrectly used parameter. This shows a lot of code was written without some basic testing along the way. Stick to the programming philosophy of building a program in increments, testing along the way (see here: A development process).

    Start small, and play around with passing arrays to functions and updating them, before attempting sophisticated code that revolves around this usage.

    Note that I didn't look any further into your code than that.

  3. #3
    Registered User
    Join Date
    Sep 2014
    Posts
    235
    Thanks for links but I have fixed it.

  4. #4
    Registered User hk_mp5kpdw's Avatar
    Join Date
    Jan 2002
    Location
    Northern Virginia/Washington DC Metropolitan Area
    Posts
    3,817
    Code:
    char ch;
    FILE* f;
    FILE* f2;
    f = fopen(configFile, "r");
    if( f != NULL ) // if config already exists, backup
        {
        f2 = fopen("kernels.bak", "w");
        while( ( ch = fgetc(f) ) != EOF )
    ch should be int not char since you are comparing against EOF. You do this correctly in your readConfig function but not here in the makeConfig function.
    "Owners of dogs will have noticed that, if you provide them with food and water and shelter and affection, they will think you are god. Whereas owners of cats are compelled to realize that, if you provide them with food and water and shelter and affection, they draw the conclusion that they are gods."
    -Christopher Hitchens

  5. #5
    Registered User
    Join Date
    Sep 2014
    Posts
    235
    Thanks for notice. I have forget to correct it.

    I have changed the function header to
    Code:
    int readConfig(char ** path, FILES ** files
    to make call like this:
    count = readConfig(&path, &files))
    using dots to access members like this
    Code:
    files[count].name=...value...
    Everything seems to be fine until I return count, than it crashes with error SIGSEGV. I cannot find out why. Yet I tried to make FILES * files and to access members with operator ->.

  6. #6
    Registered User
    Join Date
    Jun 2011
    Posts
    4,513
    I have changed the function header to...
    It doesn't look any different to me (except for missing the closing parenthesis).

    to make call like this:
    count = readConfig(&path, &files))
    This doesn't look any different, either. (Note: You should be getting an error if your actual code has that extra closing parenthesis).

    using dots to access members like this
    So that's something different. Why did you think that would work?

    This appears to have the same fundamental problem I described in my previous post.

    Everything seems to be fine until I return count, than it crashes with error SIGSEGV. I cannot find out why.
    Option 1: Heed my advice from above and start small, fixing warnings and testing as you go.
    Option 2: Learn how to use a debugger to track down problems like these.
    Option 3: Create the smallest compilable program that exhibits the problem, and post that.



    [edit] Your claim that this program runs up to a point is at odds with at least one syntax error I see in the code you originally posted. I hope you're copy/pasting your actual code, and not a hastily typed "mock-up" that doesn't represent what you're really trying to compile. That would be wasting our time, debugging typos that wouldn't be in the original code.
    Last edited by Matticus; 09-11-2014 at 01:36 PM.

  7. #7
    Registered User
    Join Date
    Jun 2011
    Posts
    4,513
    I see you're already getting ample help elsewhere -> strcpy error - C++ Forum

    I don't appreciate you wasting my time. I'm done with you.

  8. #8
    Registered User
    Join Date
    Sep 2014
    Posts
    235
    Quote Originally Posted by Matticus View Post
    I don't appreciate you wasting my time. I'm done with you.
    What's your problem man? I did solve problems with strcpy there and allocating memory. Didn't you read the question? Here I asked how to access the members.
    Approppos I started this topic after I solved the problems with strcpy.

  9. #9
    Registered User
    Join Date
    Jun 2011
    Posts
    4,513
    From other posters on that thread:

    I do predict that the caller of readFiles() will crash.

    What is FILES?
    What is files (in the function that calls readFiles)?
    How does the caller know how many files were found?
    Once again, what is the FILES * files?
    They were clearly onto some potential problems, in fact strongly related the ones you are asking about here. They had already spent time analyzing your code, and were prodding you for more information (presumably with the intent to continue helping). They were in a position to offer advice, already being somewhat familiar with the code from the time they spent helping you.

    The analysis I did was therefore redundant.

  10. #10
    Registered User
    Join Date
    Sep 2014
    Posts
    235
    Thanks for your reading of that topic and extracting the questions. I already forgot about them.

    Sorry for wasting your time spend with analysis. I thought that the previous topic on strcpy is finished.

  11. #11
    Registered User
    Join Date
    Jun 2011
    Posts
    4,513
    It's alright, perhaps I was a bit hasty with my response.

    I still stand by the advice I gave in this thread, especially from post #2:

    Quote Originally Posted by Matticus
    Start small, and play around with passing arrays to functions and updating them, before attempting sophisticated code that revolves around this usage.
    In my opinion, this is the best way to go about solving the problem (if you haven't already done so).

    I'd recommend starting with something simple like this:

    Code:
    #include <stdio.h>
    
    #define MAX_LEN 64
    #define MAX_FILES 8
    
    typedef struct
    {
        char name[MAX_LEN];
        char filename[MAX_LEN];
    } FILES;
    
    /* ... */
    
    int main(void)
    {
        FILES files[MAX_FILES];
    
        /* function call */
        /* print all data */
    
        return 0;
    }
    
    /* ... */
    Create a function that will receive the FILES array and load strings into each member, then print out all the strings in "main()".

    When you're absolutely sure you have that working, you can start adding more code - making one change at a time and testing after each. For instance, the next change could be making the struct members char pointers and allocating memory before assigning them values (be sure to check the return value of "malloc()" for success, which your original code lacked).

    Eventually, you can start incorporating this "practice code" into your actual program.

  12. #12
    Registered User
    Join Date
    Sep 2014
    Posts
    235
    Quote Originally Posted by Matticus View Post
    be sure to check the return value of "malloc()" for success, which your original code lacked
    Do you mean to check if the returned pointer is not NULL?

  13. #13
    Registered User
    Join Date
    Jun 2011
    Posts
    4,513
    Quote Originally Posted by barracuda View Post
    Do you mean to check if the returned pointer is not NULL?
    Correct.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. How to access private members in class?
    By akif13 in forum C++ Programming
    Replies: 4
    Last Post: 06-16-2014, 05:30 AM
  2. Replies: 7
    Last Post: 11-20-2013, 01:25 PM
  3. How to access members of a struct
    By Bnchs in forum C Programming
    Replies: 9
    Last Post: 03-25-2008, 02:28 PM
  4. Not able to access private data members
    By smitsky in forum C++ Programming
    Replies: 31
    Last Post: 05-09-2004, 07:06 PM
  5. Access violation on class members
    By filler_bunny in forum Windows Programming
    Replies: 2
    Last Post: 05-03-2004, 02:58 AM