?
Solved

Run time Error with populating a property of a class

Posted on 2005-03-26
24
Medium Priority
?
282 Views
Last Modified: 2010-04-01
Hello,
I get a run-time error when I start a loop of an array, where I populate a class's properties with the items in the array...Any idea why?  Here is the loop...

for( unsigned int x = 0; x < data.size(); x++ )
     {
          ItemType *objStudenType = new ItemType();
          cout << "I instantianted the objStudentType class\n";
          objStudent->item.setStudentNumber((char*)data[x][0].c_str());--->Error occurs here...
          cout << "I entered in the student number";
          objStudent->item.setFirstName((char*)data[x][1].c_str());
          objStudent->item.setLastName((char*)data[x][2].c_str());
          objStudent->item.setStudentYear((char*)data[x][3].c_str());
          objStudent->item.setCredits(atoi((char*)data[x][4].c_str()));
          objStudent->item.setGPA(atoi((char*)data[x][5].c_str()));
          cout << "I loaded all of items from the file into the class";
          insert(getLength(),objStudent->item);
          for( unsigned int y = 0; y < data[x].size(); y++ )
          {
              cout << data[x][y] << ",";
          }
          cout << endl;
     }
0
Comment
Question by:ispcorp
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 14
  • 8
  • 2
24 Comments
 
LVL 2

Author Comment

by:ispcorp
ID: 13638247
Here is the class with the properties...

#include "student.h"
#include <iostream>

using namespace std;
student::student()
{}
student::~student()
{}
void student::setStudentNumber(char *paramNewValue) const {
     strcpy(strStudentNumber,paramNewValue);
}
char *student::getStudentNumber() const{
     return strStudentNumber;
}
void student::setFirstName(char *paramNewValue) const {
     strcpy(strFirstName,paramNewValue);
}
char *student::getFirstName() const {
     return strFirstName;
}
void student::setLastName(char *paramNewValue) const {
     strcpy(strLastName,paramNewValue);
}
char *student::getLastName() const
{
     return strLastName;
}
void student::setStudentYear(char *paramNewValue) const {
     strcpy(strStudentYear,paramNewValue);
}
char *student::getStudentYear() const {
     return strStudentYear;
}
void student::setCredits(int paramNewValue)
{
     intCredits=paramNewValue;
}
int student::getCredits() const {
     return intCredits;
}
void student::setGPA(double paramNewValue)
{
     dblGPA=paramNewValue;      
}
double student::getGPA() const {
    return dblGPA;
}
void student::displayStudent() const{
     cout << "Student Number: " << getStudentNumber() << "\tFirst Name: " << getFirstName() << "\tLast Name: " << getLastName()
     << "\nStudent Year: " << getStudentYear() << "\tCredits: " << getCredits() << "\tGPA: " << getGPA();
}



0
 
LVL 15

Expert Comment

by:efn
ID: 13638429
How is the data array declared?

How is strStudentNumber declared?

You can avoid casts if you declare parameters const char * instead of char *.
0
 
LVL 2

Author Comment

by:ispcorp
ID: 13639107
Sorry here is my Student.H for your review....

#include <string>
#include <cstddef>
class student
{
      public:
            student();
            ~student();
            void setStudentNumber(char *paramNewValue) const;
            char *getStudentNumber() const;
            void setFirstName(char *paramNewValue) const;
            char *getFirstName() const;
            void setLastName(char *paramNewValue) const;
            char *getLastName() const;
            void setStudentYear(char *paramNewValue) const;
            char *getStudentYear() const;
            void setCredits(int paramNewValue);
            int getCredits() const;
            void setGPA(double paramNewValue);
            double getGPA() const;
            void displayStudent() const;
      private:
            char *strStudentNumber;
            char *strFirstName;
            char *strLastName;
            char *strStudentYear;
            int intCredits;
            double dblGPA;
};

The data array is declared as follows..
vector < vector <string> > data;
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 15

Expert Comment

by:efn
ID: 13639756
strStudentNumber is a pointer to char.  As far as I can see, it is never initialized to point to anything.  When student::setStudentNumber calls strcpy with strStudentNumber as the first parameter, strcpy tries to copy characters to the location specified by strStudentNumber.  Because the strStudentNumber pointer has not been initialized, strcpy writes to an invalid address and you get a run-time error.

If you want to store a character string, somehow you have to get storage allocated for it.  Just declaring a pointer does not automatically allocate anything for the pointer to address.  There are a couple of ways you could fix it.

One would be to make strStudentNumber and the other character string variables character arrays instead of character pointers.  For example:

char strStudentNumber[20];

Then strcpy will work.  When you pass the array name as a parameter, it automatically gets converted to a pointer to the array's first element.  This will be the simplest design if you want to be able to read students from and write students to secondary storage.  The only disadvantage is that you have to set limits on the sizes of the strings at compile time.

Another solution would be to make the string variables objects of a string class such as the one in the standard library.  Then instead of strcpy, you could just use an assignment statement, and you wouldn't have to worry about size limits.  However, if you wanted to write out a student to disk, you would have to serialize it first, that is, convert it to a sequence of bytes.  You can't just write out a string object without serializing it.
0
 
LVL 86

Expert Comment

by:jkr
ID: 13639824
You also could dynamically allocate the memory, e.g.

student::student()
{

strStudentNumber= NULL;
strFirstName= NULL;
strLastName= NULL;
strStudentYear= NULL;
}
student::~student()
{
if(strStudentNumber) delete[] strStudentNumber;
if(strFirstName) delete[] strFirstName;
if(strLastName) delete[] strLastName;
if(strStudentYear) delete[] strStudentYear;
}

void student::AllocAndSet(char** param, char* newVal) {

    if ( *param) delete [] param;

    *param = new char[strlen(newVal)+1];

    strcpy(*param,newValue);
}

void student::setStudentNumber(char *paramNewValue) const {
    AllocAndSet(&strStudentNumber,paramNewValue);
}
char *student::getStudentNumber() const{
    return strStudentNumber;
}
void student::setFirstName(char *paramNewValue) const {
    AllocAndSet(&strFirstName,paramNewValue);
}
char *student::getFirstName() const {
    return strFirstName;
}
void student::setLastName(char *paramNewValue) const {
    AllocAndSet(&strLastName,paramNewValue);
}
char *student::getLastName() const
{
    return strLastName;
}
void student::setStudentYear(char *paramNewValue) const {
    AllocAndSet(&strStudentYear,paramNewValue);
}

This would give you the advantage to not be limited to a fixed field length.
0
 
LVL 2

Author Comment

by:ispcorp
ID: 13641227
Hey JKR,
Your above didn't work, I still get the same error in the exact same place.   Any other suggestions would be appreciated.

0
 
LVL 86

Expert Comment

by:jkr
ID: 13641295
Hmm, also with efn's method? Are you sure that the 2d-array gotinitialized and filles with data properly? You could just check that by using e.g.

void student::setStudentNumber(char *paramNewValue) const {
   cout << "New value to set: " << paramNewValue << endl;
   AllocAndSet(&strStudentNumber,paramNewValue);
}
0
 
LVL 2

Author Comment

by:ispcorp
ID: 13641303
Hey efn,
I tried declaring the variables as you suggested, and I got the same error...

For instance, I made the variables such as char strStudentNumber[20], and the parameter values the same thing, but still the same error.
0
 
LVL 2

Author Comment

by:ispcorp
ID: 13641329
No JKR, never reached that cout line you just gave me...Interesting...I'm wondering what I'm missing.
0
 
LVL 2

Author Comment

by:ispcorp
ID: 13641341
You instantiate a class object by setting it to new right?

Such as this...

ItemStudentType *objStudentType = new ItemStudentType();
0
 
LVL 86

Accepted Solution

by:
jkr earned 2000 total points
ID: 13641349
That's why I'm asking whether you are sure the vector(s) have been filled correctly - could that be the problem? You could add that same kind of diagnostic output to the "reading" code to see whether everything is read and stored the way it should.
0
 
LVL 2

Author Comment

by:ispcorp
ID: 13641353
Yes, the vectors have been filled correctly...If I take out the set statements, I can do a for loop with cout and it will display all the items in the array.
0
 
LVL 86

Expert Comment

by:jkr
ID: 13641365
Stupid Q - you are using

         ItemType *objStudenType = new ItemType();
         cout << "I instantianted the objStudentType class\n";
         objStudent->item.setStudentNumber((char*)data[x][0].c_str());


Shouldn't that be

         ItemType *objStudent= new ItemType(); // Note: No 'Type' ending, a typo or maybe the error?
         cout << "I instantianted the objStudentType class\n";
         objStudent->item.setStudentNumber((char*)data[x][0].c_str());
0
 
LVL 2

Author Comment

by:ispcorp
ID: 13641381
No it was just a typo on my part...

My code reads what you put for the second line...This is killing me

0
 
LVL 86

Expert Comment

by:jkr
ID: 13641392
Could you post the whole code along with a sample file to read in?
0
 
LVL 2

Author Comment

by:ispcorp
ID: 13641401
#include "studentactionlist.h"
#include <stdexcept>
#include<cstddef>
#include<cassert>
#include "stdlib.h"

StudentActionList::StudentActionList():StudentList()
{}
StudentActionList::~StudentActionList()
{}
StudentActionList::StudentNode *StudentActionList::getStudentByStudentNumber(char *paramStudentNumber) throw (ListIndexOutOfRangeException)
{
    bool blnIsItem;
    int itSize = getLength();
    char *strStudentNumber;
    ItemStudentType objStudent;
   
    if (itSize == 0)
    {
       throw ListIndexOutOfRangeException("ListIndexOutOfRangeException: They're no students loaded.");
    }
    else
    {
        StudentNode *objStudent = head;
        for (int i=0; i < itSize; ++i)
        {
            strStudentNumber=objStudent->item.getStudentNumber();
            if (strcmp(strStudentNumber,paramStudentNumber))
            {
               blnIsItem=true;
               break;
            }
            StudentNode *cur=cur->next;
            objStudent->item=cur->item;            
        }
        if (blnIsItem)
        {
            return objStudent;
        }
        else
        {
            return NULL;
        }
    }
}
void StudentActionList::deleteStudent(ItemStudentType *paramStudent) throw(ListIndexOutOfRangeException)
{
     int itSize = getLength();
     //ItemStudentType objStudent;
     if (itSize == 0)
     {
        throw ListIndexOutOfRangeException("ListIndexOutOfRangeException: Item list is empty.");
     }    
     else
     {
         StudentNode *objStudent = head;
         StudentNode *prev=NULL;
         for (int i=0; i < itSize; ++i)
         {
             StudentNode *tmp=objStudent;
             prev=objStudent;
             objStudent=objStudent->next;
             if (strcmp(tmp->item.getStudentNumber(),paramStudent->getStudentNumber()))
             {
                remove(i);
                //if (prev!=NULL) prev->next = objStudent;
                //delete tmp;
             }
             //StudentNode *cur=cur->next;
             //objStudent->item=cur->item;          
         }
     }
}
void StudentActionList::loadStudents()
{
     ItemStudentType *objStudent;
     ItemType temp;
     ifstream in("test.csv");
     vector < vector <string> > data;
     string element, delimiters = ",\n\r";
     int row = 0;
     char ch;

     data.push_back( vector <string>() );

     while( in.read( (char*)&ch, 1 ) )
     {

          if( delimiters.find_first_of(ch) == delimiters.npos )
          {
               element += ch;
          }
          else
          {
               if( ch != '\r' )
               {
                    data[row].push_back( element );
                    element = "";

                    if( ch == '\n' )
                    {
                         data.push_back( vector <string>() );
                         row++;
                    }
               }
          }
     }

     if( element.size() > 0 )
          data[row].push_back( element );

     in.close();
     try
     {
         for( unsigned int x = 0; x < data.size(); x++ )
         {
              StudentNode *objStudent = new StudentNode();
              cout << "I instantianted the objStudentType class\n";
              objStudent->item.setStudentNumber((char*)data[x][0].c_str());
              cout << "I entered in the student number";
              objStudent->item.setFirstName((char*)data[x][1].c_str());
              objStudent->item.setLastName((char*)data[x][2].c_str());
              objStudent->item.setStudentYear((char*)data[x][3].c_str());
              objStudent->item.setCredits(atoi((char*)data[x][4].c_str()));
              objStudent->item.setGPA(atoi((char*)data[x][5].c_str()));
              cout << "I loaded all of items from the file into the class";
              //insert(getLength(),*objStudent);
              for( unsigned int y = 0; y < data[x].size(); y++ )
              {
                  cout << data[x][y] << ",";
              }
              cout << endl;
         }
     }
     catch(exception ex)
     {
              cout << ex.what();
     }    
}


0
 
LVL 2

Author Comment

by:ispcorp
ID: 13641402
#include "studentlist.h"
#include <iostream>
#include <string>

#include <iomanip>
#include <fstream>
#include <vector>

typedef student ItemStudentType;
class  StudentActionList: public StudentList
{
      public:
            StudentActionList();
            ~StudentActionList();
            struct StudentNode
        {
               ItemStudentType item;
               StudentNode *next;
        };
            StudentNode *getStudentByStudentNumber(char *paramStudentNumber)
             throw(ListIndexOutOfRangeException);
            void deleteStudent(ItemStudentType *paramStudent)
                 throw(ListIndexOutOfRangeException);        
        void loadStudents();
    private:
           StudentNode *head;
};

0
 
LVL 2

Author Comment

by:ispcorp
ID: 13641406
#include "ListException.h"
#include "ListIndexOutOfRangeException.h"
#include "student.h"
#include <iostream>
#include <list>

typedef student ItemType;
const int MAX=15;
class StudentList
{
      public:
            StudentList();
            ~StudentList();
            bool isEmpty() const;
            int getLength() const;
            void insert(int index,ItemType newItem)
                 throw(ListIndexOutOfRangeException);
        void remove(int index)
             throw(ListIndexOutOfRangeException);
        void retreive(int index, ItemType& dataItem) const
             throw(ListIndexOutOfRangeException);
      private:
            struct Node
            {
                   ItemType item;
                   Node *next;
            };
            int size;
            Node *find(int index) const;
            Node *head;
};
0
 
LVL 2

Author Comment

by:ispcorp
ID: 13641409
#include "studentlist.h" // class's header file
#include <cstddef>
#include <cassert>

StudentList::StudentList(): size(0),head(NULL)
{}
StudentList::~StudentList()
{}
bool StudentList::isEmpty() const
{
     return size == 0;
}
int StudentList::getLength() const
{
    return size;
}
StudentList::Node *StudentList::find(int index) const
{
    if ((index < 1) || (index > getLength()))
       return NULL;
    else
    {
        Node *cur = head;
        for (int skip = 1; skip < index; ++skip)
            cur = cur->next;
        return cur;
    }
}
void StudentList::retreive(int index,ItemType& dataItem) const  throw (ListIndexOutOfRangeException)
{
     if ((index < 1) || (index > getLength()))
        throw ListIndexOutOfRangeException("ListOutOfRangeException: retrieve index out of range");
     else
     {
         Node *cur = find(index);
         dataItem = cur->item;
     }
}
void StudentList::insert(int index,ItemType newItem) throw (ListIndexOutOfRangeException)
{
     int newLength = getLength() + 1;
     if ((index < 1) || (index > newLength))
        throw ListIndexOutOfRangeException("ListOutRangeException: insert index out of range");
     else
     {
         Node *newPtr = new Node;
         if (newPtr == NULL)
            throw ListException("ListException: insert cannot allocate memory");
         else if(size==MAX)
              throw ListException("ListException: maximum number of students have been reached");
         else
         {
             size = newLength;
             newPtr->item=newItem;
             if (index==1)
             {
                newPtr->next=head;
                head=newPtr;
             }
             else
             {
                 Node *prev = find(index-1);
                 newPtr->next=prev->next;
                 prev->next=newPtr;
             }
         }
     }
}
void StudentList::remove(int index) throw (ListIndexOutOfRangeException)
{
     Node *cur;
     if ((index < 1) || (index > getLength()))
        throw ListIndexOutOfRangeException("ListOutRangeException: remove index out of range");
     else
     {
         if (index ==1)
         {
            cur = head;
            head = head->next;
         }
         else
         {
             Node *prev = find(index-1);
             cur = prev->next;
             prev->next = cur->next;
         }
         cur->next=NULL;
         delete cur;
         cur=NULL;
     }
}
0
 
LVL 86

Expert Comment

by:jkr
ID: 13641437
If you now could provide the files' names... :o)
0
 
LVL 86

Expert Comment

by:jkr
ID: 13641440
... and the input file as well.
0
 
LVL 2

Author Comment

by:ispcorp
ID: 13641467
Well the file is called test.csv....

And the file looks like the following...

131993344,Thomas,Chaar,Sophmore,60,3
131821222,Sammy,Chaar,Junior,80,4
393393933,Amine,Chaar,Senior,120,4
0
 
LVL 2

Author Comment

by:ispcorp
ID: 13641474
JKR....I can't  beleive it....I found out what it was...You were absolutely right, the vector didn't have any items in it because the file was not in the directory.  It was in a separate directory I used to test out the code I was using in the class.  I feel so stupid....but thanks for your help.  I'll give you the points.
0
 
LVL 86

Expert Comment

by:jkr
ID: 13641484
You're most welcome - we have a proverb here that describes that as "not being able to see the woods because of all those damned trees" :o)
0

Featured Post

What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

What is C++ STL?: STL stands for Standard Template Library and is a part of standard C++ libraries. It contains many useful data structures (containers) and algorithms, which can spare you a lot of the time. Today we will look at the STL Vector. …
Basic understanding on "OO- Object Orientation" is needed for designing a logical solution to solve a problem. Basic OOAD is a prerequisite for a coder to ensure that they follow the basic design of OO. This would help developers to understand the b…
The viewer will learn how to pass data into a function in C++. This is one step further in using functions. Instead of only printing text onto the console, the function will be able to perform calculations with argumentents given by the user.
The viewer will be introduced to the member functions push_back and pop_back of the vector class. The video will teach the difference between the two as well as how to use each one along with its functionality.

762 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question