CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 14 of 14
  1. #1
    Join Date
    Aug 2002
    Posts
    12

    Writing to a struct in an array

    I have a structure in which there is another structure which has an array of 512 pointers to it.. if that made no sense:
    Code:
    struct TREEFILE
    {
        char *name;
        struct FILEINFO
        {
            char *field;
            char *key;
            char *value;
        }*fileInfo[512];
    };
    What I want to do is assign values to that substructure with the array being at any one of those 512, once again if that made no sense.. lets say Ive already set int arrayLine to be 0:
    Code:
    strcpy(tFile.fileInfo[arrayLine]->key, "_FIELD_");
    strcpy(tFile.fileInfo[arrayLine]->key, "_KEY_");
    strcpy(tFile.fileInfo[arrayLine]->key, "_VALUE_");
    This compiles all well and fine, but as soon as the program runs I get an illegal opperation... and those lines, well any one by itself is causing the problem. Ive also figured out that I only get problems when I try to add a value to that sub-structure. So this works:
    Code:
    tFile.fileInfo[arrayLine]->key;
    /* But this wont */
    strcpy(tFile.fileInfo[arrayLine]->key, "_VALUE_");
    Im lead to believe my problem could be allocating the right amount of memory, or some problem with writing to memory.
    Sorry that this may be tough to understand, but its 4am
    If anyone has any ideas or answers thatd be great. Thanks.

  2. #2
    Join Date
    Oct 2001
    Location
    Dublin, Eire
    Posts
    880
    You need to reserve memory for every single char* in which you want to write. And as long as you don't reserve memory, you'd better make all of it point to NULL.

    You need a constructor for your structure that will NULL all pointers at the creation of the object.

    Then you'd better use a member function of your structure to assign values instead of a direct use of strcpy. This way you will be able to handle the memory assignment.

    Your asignment function should be something like:
    Code:
    
    AssignKey(int arrayLine, char newkey[])
    {
      if(tFile.fileInfo[arrayLine] == NULL)
      {
        tFile.fileInfo[arrayLine] = new FILEINFO;
        tFile.fileInfo[arrayLine]->field = NULL;
        tFile.fileInfo[arrayLine]->key = NULL;
        tFile.fileInfo[arrayLine]->value = NULL;
      }
    
      if(tFile.fileInfo[arrayLine]->key != NULL) 
        delete [] tFile.fileInfo[arrayLine]->key;
    
      tFile.fileInfo[arrayLine]->key = new char[strlen(newkey)+1];
      strcpy(tFile.fileInfo[arrayLine]->key, newkey);
    
      
    }
    Just for your information, I have written that without testing anything, it requires that at least the memory for your array object was reserved in the constructor. If you want to go with this,, make sure that everything is ok, this is just a starting point.
    Elrond
    A chess genius is a human being who focuses vast, little-understood mental gifts and labors on an ultimately trivial human enterprise.
    -- George Steiner

  3. #3
    Join Date
    Apr 1999
    Location
    Altrincham, England
    Posts
    4,470
    You appear to have two missing memory allocations:

    1) For each entry in fileInfo, you need to allocate enough memory for a FILEINFO structure, and

    2) For each (allocated) FILEINFO structure, you need to allocate memory for the field, key and value fields.

    I suspect that 2) is the root of your problem.

    Oh, and don't forget that "name" also needs memory allocated for it.
    Correct is better than fast. Simple is better than complex. Clear is better than cute. Safe is better than insecure.
    --
    Sutter and Alexandrescu, C++ Coding Standards

    Programs must be written for people to read, and only incidentally for machines to execute.

    --
    Harold Abelson and Gerald Jay Sussman

    The cheapest, fastest and most reliable components of a computer system are those that aren't there.
    -- Gordon Bell


  4. #4
    Join Date
    Aug 2002
    Posts
    12
    Alright, I gotcha, one more question... Im still new with structures, so how do I add a constructor and destructor. I dont see how it can be exactly like you would with classes. Would you have to just call that allocate memory function before you do anything wiht that structure?

  5. #5
    Join Date
    Oct 2001
    Location
    Dublin, Eire
    Posts
    880
    A structure is a class with its member public instead of private by default.

    You can add a constructor to a structure exactly as you would add a constructor in a class:

    Code:
    
    struct TREEFILE
    {
        char *name;
        struct FILEINFO
        {
            char *field;
            char *key;
            char *value;
        }*fileInfo[512];
    
        TREEFILE();
        ~TREEFILE();
    };
    
    
    TREEFILE::TREEFILE()
    {
      int i;
      for( i=0; i<512; i++)
        fileInfo[i] = NULL;
    }
    
    TREEFILE::~TREEFILE()
    {
      int i;
      for( i=0; i<521; i++)
      {
        if( fileInfo[i] )
        {
          if( fileInfo[i]->field ) delete [] fileInfo[i]->field;
          if( fileInfo[i]->key ) delete [] fileInfo[i]->key;
          if( fileInfo[i]->value ) delete [] fileInfo[i]->value;
          delete fileInfo[i];
        }
      }
    }
    I think that's it.
    Elrond
    A chess genius is a human being who focuses vast, little-understood mental gifts and labors on an ultimately trivial human enterprise.
    -- George Steiner

  6. #6
    Join Date
    Aug 2002
    Posts
    12
    Well crap, thats easy Thanks man.

  7. #7
    Join Date
    Aug 2002
    Posts
    12
    Hmn, well, I got it to write, but in the deconstructor where it deletes all the allocated memory... the program crashes.

  8. #8
    Join Date
    Jun 2002
    Posts
    49
    the for loop in the destructor is taking you out of bounds (521 instead of 512)

    -KS
    Last edited by keyser_soze@usa; August 1st, 2002 at 12:45 PM.

  9. #9
    Join Date
    Aug 2002
    Posts
    12
    Ya, I got that, but Ive narrowed it down to this specific line
    Code:
    delete fileInfo[i];
    Why wouldnt it be able to delete the entire part of the array?

  10. #10
    Join Date
    Apr 1999
    Location
    Altrincham, England
    Posts
    4,470
    Code:
    #include <string>
    #include <vector>
    
    struct TREEFILE
    {
        struct FILEINFO
        {
            std::string field;
            std::string key;
            std::string value;
        };
    
        std::string name;
        std::vector<FILEINFO> fileInfo;
    };
    No memory problems with that version. No constructors or destructors needed. Not restricted 512 elements in the vector, or wasted space if less than 512 are needed.
    Correct is better than fast. Simple is better than complex. Clear is better than cute. Safe is better than insecure.
    --
    Sutter and Alexandrescu, C++ Coding Standards

    Programs must be written for people to read, and only incidentally for machines to execute.

    --
    Harold Abelson and Gerald Jay Sussman

    The cheapest, fastest and most reliable components of a computer system are those that aren't there.
    -- Gordon Bell


  11. #11
    Join Date
    Oct 2001
    Location
    Dublin, Eire
    Posts
    880
    It depends how you allocated the memory.

    May be a delete [] fileInfo will be more appropriate after the loop.
    Elrond
    A chess genius is a human being who focuses vast, little-understood mental gifts and labors on an ultimately trivial human enterprise.
    -- George Steiner

  12. #12
    Join Date
    Aug 2002
    Posts
    12
    Alright, thanks guys...
    Graham: Im trying to stay away from any of those classes and take the hard way out
    Actually Im trying to get a better understanding of how memory allocation is handled.
    Last edited by AndrewJenkins; August 2nd, 2002 at 09:31 AM.

  13. #13
    Join Date
    Apr 1999
    Location
    Altrincham, England
    Posts
    4,470
    Well, I just hope that doing what you're doing will help to convince you that there is a better way.....
    Correct is better than fast. Simple is better than complex. Clear is better than cute. Safe is better than insecure.
    --
    Sutter and Alexandrescu, C++ Coding Standards

    Programs must be written for people to read, and only incidentally for machines to execute.

    --
    Harold Abelson and Gerald Jay Sussman

    The cheapest, fastest and most reliable components of a computer system are those that aren't there.
    -- Gordon Bell


  14. #14
    Join Date
    May 1999
    Location
    Southern California
    Posts
    12,266

    Re: Writing to a struct in an array

    In the following:
    Code:
    strcpy(tFile.fileInfo[arrayLine]->key, "_FIELD_");
    strcpy(tFile.fileInfo[arrayLine]->key, "_KEY_");
    strcpy(tFile.fileInfo[arrayLine]->key, "_VALUE_");
    The data you are copying from are constants. The destination is specifed using ponters, as others have indicated. You need to have storage for the strings pointed to. Yet in the case of constants the memory will already exist. So you might be able to do:
    Code:
    tFile.fileInfo[arrayLine]->key = "_FIELD_";
    tFile.fileInfo[arrayLine]->key = "_KEY_";
    tFile.fileInfo[arrayLine]->key = "_VALUE_";
    That sets the pointers to the address of the string constants. This would not work if you need to change the strings.

    Alternatively something such as the following would work:
    Code:
    tFile.fileInfo[arrayLine]->key = new char[8];
    strcpy(tFile.fileInfo[arrayLine]->key, "_FIELD_");
    tFile.fileInfo[arrayLine]->key = new char[6];
    strcpy(tFile.fileInfo[arrayLine]->key, "_KEY_");
    tFile.fileInfo[arrayLine]->key = new char[8];
    strcpy(tFile.fileInfo[arrayLine]->key, "_VALUE_");
    // Use the strings, then when you are through:
    delete [] tFile.fileInfo[arrayLine]->key;
    delete [] tFile.fileInfo[arrayLine]->key;
    delete [] tFile.fileInfo[arrayLine]->key;
    Doing fancy things like constructors and destructors is probably worthwhile but probably are also not necessary.
    Last edited by Sam Hobbs; August 2nd, 2002 at 07:38 PM.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured