segmentation fault while loading data from a file in C++ -


the title of question might have been title many other questions on site, however, experiencing strangest thing i've ever had deal in whole academic life.

i assigned design binary search tree database contains long list of company's employee records. have implemented project , worked fine, until received email professor asking in class log linux-powered server via ssh , verify project compiles , behaves expected on there.

the source code compiled fine, however, when run application , tell load list of 3000 records of file, run segmentation fault @ 543th record (line in file).

my question is: causing problem, considering code worked fine on own machine?

does matter, size of project, how memory assigned me? possible running out of memory while loading data?

even though 100% sure problem not in code, still think convenient @ piece of code , try spot problem.

here's employee class:

class employee { public:      employee(){}      employee(std::string first_name, std::string last_name, unsigned int id)     {         this->first_name = first_name;         this->last_name = last_name;         this->id = id;     }      std::string first_name;     std::string last_name;     unsigned int id;     employee * left, * right; };//*root; 

this function using load file database:

void createbst(bstree & tree) {     string file_name;      cout << "enter database file path: ";     cin >> file_name;      ifstream file_reader (file_name.c_str());    //  if (file_reader == null)   //  {    //     error("\nerror: invalid file path provided!\n\n");    ///     return;    // }      string line;     (;;)     {         if (!getline(file_reader, line))             break;          string tokens[3];         split(line, tokens);          string first_name, last_name;         unsigned int id;          last_name = tokens[0];         first_name = tokens[1];         id = std::atoi(tokens[2].c_str());      //    cout << "inserting: " << tokens[2] << "\t" << tokens[0] << "\t" << tokens[1] << endl;          // insert new employee object bstree         tree.insert(new employee(first_name, last_name, id));     }      cout << endl << endl << "all employee records have been inserted database successfully." << endl << endl;      // close file     file_reader.close(); } 

and here binary search tree (bstree):

#include <iomanip> #include <iostream> #include "bstree.h"  //-------------------------------------------- // function: bstree() // purpose: class constructor. //-------------------------------------------- bstree::bstree() {     count = 0;     root = null; }  //-------------------------------------------- // function: ~bstree() // purpose: class destructor. //-------------------------------------------- bstree::~bstree() {     cleartree(root);     return; }  //-------------------------------------------- // function: cleartree() // purpose: perform recursive traversal of //        tree destroying nodes. //-------------------------------------------- void bstree::cleartree(employee *t) {     if(t==null) return;  // nothing clear     if(t->left != null) cleartree(t->left); // clear left sub-tree     if(t->right != null) cleartree(t->right); // clear right sub-tree     delete t;    // destroy node     return; }  //-------------------------------------------- // function: isempty() // purpose: return true if tree empty. //-------------------------------------------- bool bstree::isempty() {     return(root == null); }   //-------------------------------------------- // function: dupnode() // purpose: duplicate node in tree.  //        used allow returning complete //        structure tree without giving //        access tree through pointers. // preconditions: none // returns: pointer duplicate of node arg //-------------------------------------------- employee *bstree::dupnode(employee * t) {     employee *dupnode;      dupnode = new employee();     *dupnode = *t;    // copy data structure     dupnode->left = null;    // set pointers null     dupnode->right = null;     return dupnode; }   //-------------------------------------------- // function: searchtree() // purpose: perform iterative search of tree , //        return pointer treenode containing //        search key or null if not found. // preconditions: none // returns: pointer duplicate of node found //-------------------------------------------- employee *bstree::searchtree(unsigned int key) {     employee *temp;      temp = root;     while((temp != null) && (temp->id != key))     {         if(key < temp->id)             temp = temp->left;  // search key comes before node.         else             temp = temp->right; // search key comes after node     }      if(temp == null)         return temp;    // search key not found     else         return(dupnode(temp));    // found return duplicate }    //-------------------------------------------- // function: insert() // insert new node tree. // preconditions: none // returns: int (true if successful, false otherwise) //-------------------------------------------- bool bstree::insert(employee *newnode) {     employee *temp;     employee *back;      temp = root;     = null;      while(temp != null) // loop till temp falls out of tree     {         = temp;         if(newnode->id < temp->id)             temp = temp->left;         else if (newnode->id > temp->id)             temp = temp->right;         else             return false;     }      // attach new node node points     if(back == null) // attach root node in new tree         root = newnode;      else     {         if(newnode->id < back->id)             back->left = newnode;         else if (newnode->id > back->id)             back->right = newnode;         else             return false;     }     return true; }   //-------------------------------------------- // function: insert() // insert new node tree. // preconditions: none // returns: int (true if successful, false otherwise) //-------------------------------------------- bool bstree::insert(unsigned int key, string first_name, string last_name) {      employee *newnode;      // create new node , copy data     newnode = new employee();     newnode->id = key;     newnode->first_name = first_name;     newnode->last_name = last_name;     newnode->left = newnode->right = null;      // call other insert() actual insertion     return(insert(newnode)); }  //-------------------------------------------- // function: delete() // purpose: delete node tree. // preconditions: tree contains node delete // returns: int (true if successful, false otherwise) //-------------------------------------------- bool bstree::delete(unsigned int key) {     employee *back;     employee *temp;     employee *delparent;    // parent of node delete     employee *delnode;      // node delete      temp = root;     = null;      // find node delete     while((temp != null) && (key != temp->id))     {         = temp;         if(key < temp->id)             temp = temp->left;         else             temp = temp->right;     }      if(temp == null) // didn't find 1 delete         return false;      else     {         if(temp == root) // deleting root         {             delnode = root;             delparent = null;         }         else         {             delnode = temp;             delparent = back;         }     }      // case 1: deleting node no children or 1 child     if(delnode->right == null)     {         if(delparent == null)    // if deleting root         {             root = delnode->left;             delete delnode;             return true;         }         else         {             if(delparent->left == delnode)                 delparent->left = delnode->left;             else                 delparent->right = delnode->left;                 delete delnode;             return true;         }     }     else // there @ least 1 child     {         if(delnode->left == null)    // 1 child , on right         {             if(delparent == null)    // if deleting root             {                 root = delnode->right;                 delete delnode;                 return true;             }             else             {                 if(delparent->left == delnode)                     delparent->left = delnode->right;                 else                     delparent->right = delnode->right;                 delete delnode;                 return true;             }         }         else // case 2: deleting node 2 children         {             // find replacement value.  locate node             // containing largest value smaller             // key of node being deleted.             temp = delnode->left;             = delnode;             while(temp->right != null)             {                 = temp;                 temp = temp->right;             }             // copy replacement values node deleted             delnode->id = temp->id;             delnode->first_name = temp->first_name;             delnode->last_name = temp->last_name;              // remove replacement node tree             if(back == delnode)                 back->left = temp->left;             else                 back->right = temp->left;             delete temp;             return true;         }     } }   //-------------------------------------------- // function: printone() // purpose: print data in 1 node of tree. // preconditions: none // returns: void //-------------------------------------------- void bstree::printone(employee *t) {     cout << t->id << "\t\t" << t->first_name << "\t\t" << t->last_name << endl; }    //-------------------------------------------- // function: printall() // purpose: print tree using recursive //        traversal // preconditions: none // returns: void //-------------------------------------------- void bstree::printall(employee *t) {     if(t != null)     {         printall(t->left);         printone(t);         printall(t->right);     } }   //-------------------------------------------- // function: printtree() // purpose: print tree using recursive //        traversal.  gives user access //        printall() without giving access //        root of tree. // preconditions: none // returns: void //-------------------------------------------- void bstree::printtree() {     printall(root); }   void bstree::savetofile(const char * filename) {     ofstream file_writer;     file_writer.open(filename);     savetofile(file_writer, root);     file_writer.close(); }  void bstree::savetofile(ofstream & file_writer, employee * t) {     if (t != null)     {         savetofile(file_writer, t->left);         file_writer << t->last_name;         file_writer << "\t";         file_writer << t->first_name;         file_writer << "\t";         file_writer << t->id;         file_writer << "\n";         savetofile(file_writer, t->right);     }  } 

neither of employee constructors initialize either left or right pointers null. particularly worrisome copy-constructor, parameterized constructor pain show through:

when loading file this:

tree.insert(new employee(first_name, last_name, id)); 

which fires constructor:

employee(std::string first_name, std::string last_name, unsigned int id) {     this->first_name = first_name;     this->last_name = last_name;     this->id = id; } 

nowhere in above left , right member pointers assigned anything. indeterminate , therefore garbage. when this:

bool bstree::insert(employee *newnode) {     employee *temp;     employee *back;      temp = root;     = null;      while(temp != null) // loop till temp falls out of tree     {         = temp;         if(newnode->id < temp->id)             temp = temp->left;         else if (newnode->id > temp->id)             temp = temp->right;         else             return false;     }      // attach new node node points     if(back == null) // attach root node in new tree         root = newnode;      else     {         if(newnode->id < back->id)             back->left = newnode;         else if (newnode->id > back->id)             back->right = newnode;         else             return false;     }     return true; } 

you're chasing pointers not valid, , indeed cannot evaluated less dereferenced without invoking undefined behavior.

this not going turn online debugging session. need initialize all members of object class, ideally in initializer list:

class employee { public:      // note: shouldn't *needed*     employee() : id(), left(), right() {}      // parameterized constructor     employee(const std::string& first, const std::string& last, unsigned int id)         : first_name(first)         , last_name(last)         , id(id)         , left(), right()     {     }       // copy-ctor. retains values; child pointers set null     employee(const employee& obj)         : first_name(obj.first_name)         , last_name(obj.last_name)         , id(obj.id)         , left(), right()     {     }      // assignment operator. not copy child pointers     employee& operator =(const employee& obj)     {         first_name = obj.first_name;         last_name = obj.last_name;         id = obj.id;     }      std::string first_name;     std::string last_name;     unsigned int id;     employee * left, * right; }; 

normally code assignment operator use copy-constructor implementing copy/swap idiom. in case overkill, since object has no actual dynamic-managed members ( i.e. members object responsible creating/destroying).

anyway, above big issue, , did not take time dissect actual tree management code beyond insertion logic. wouldn't surprised if there defect lurking in delete operation, tedious binary trees. should enough further down road.


Comments

Popular posts from this blog

java - WrongTypeOfReturnValue exception thrown when unit testing using mockito -

php - Magento - Deleted Base url key -

android - How to disable Button if EditText is empty ? -