MESSAGE
DATE | 2011-03-20 |
FROM | Ruben Safir
|
SUBJECT | Subject: [NYLXS - HANGOUT] [ruben@mrbrklyn.com: Nulls and Zeros in C++]
|
I'm having a very difficult time returning NULLS in my program which started out as an exercise of Linked Lists based on Lippman, but has evolved as I test out new skills and methods. I've templated it an then I added some hooks for MYSQLb but I've run into trouble with returning NULL values of zero's, especially with the operator[] which requires the return value being a reference. Let me copy and past a copy of the entire program, since it is complex for me, but likely to be run of the mill for the advanced C++ programmers here.
This is the main header file which was originally broken into a header and a .cpp file but has since been combined to make the templates happy ================================================================================ #ifndef LINKLIST_H #define LINKLIST_H #endif #include
namespace CHAINLIST{ template class NODE{ public: NODE( unk value, NODE *item_to_link_to = 0); inline unk value(); inline unk& value_ref(); inline void value(unk); inline NODE * next(); inline NODE& next_ref(); inline void next(NODE *); NODE * err_node; unk err_value;
~NODE();
private: unk _value; NODE *_next; };
template inline NODE::NODE(unk value, NODE *item): _value(value) { if (!item){ //std::cout << "_value=> " << _value << std::endl; _next = 0; } else{ //std::cout << "insert after _value=> " << _value << std::endl; //_next = item->_next; next(item->next()); item->next(this);
//inserts after on construction } };
template inline unk NODE::value(){ if(this) return _value; else{ return 0; } }
template inline unk& NODE::value_ref(){ if(this) return _value; else{ return err_value; } } template inline void NODE::value(unk val){ _value = val; }
template inline NODE * NODE::next(){ if(this != NULL) { return _next; } else { return 0; } }
template inline NODE& NODE::next_ref(){ if(this != NULL) { return *_next; } else { return 0; } }
template inline void NODE::next(NODE * nxt){ _next = nxt; }
template class LIST{ public: LIST() : _at_front(0), _at_end(0), _size(0) {} inline int size(); inline void insert(NODE *, unk); inline void insert(unk); inline void front(unk); inline void up_size(); inline void down_size(); void display(std::ostream &os = std::cout); void remove_front(); void remove_all(); void remove_item(unk); void remove_item(NODE *); NODE * find(unk); NODE * find_all(unk, NODE * last = NULL ); void sort(LIST& m );// add a sort algorithm - shell sort
unk& operator[](int);
unk err = 0;
~LIST();
private: NODE *_at_front; NODE *_at_end; int _size; LIST(const LIST&); LIST& operator=( const LIST&); };
template inline unk& LIST::operator[](const int i){ //std::cout << "Size of List is " << size() << std::endl; if( i >= size()){ std::cerr << "Index larger that List" << std::endl; return err; } NODE * cur = _at_front; int place; for(place = 0; place < size(); cur = cur->next(), ++place){ if (place == i){ unk &k = cur->value_ref(); unk &j = k; std::cout << "j ==> " << j << " k==> " << k << std::endl; std::cout << "refernce value ==> " << cur->value_ref() << std::endl; return j; } } std::cerr << "Errror - This shouldn't get through the list without finding the index" << std::endl; return err;
}
template inline int LIST::size(){return _size;}
template inline LIST::~LIST(){remove_all();}
template inline void LIST::insert(NODE *ptr, unk value){ std::cout << "insert: ptr =>" << ptr << " value =>" << value << std::endl; //std::cout << "insert: ptr =>" << ptr << " value =>" << value << std::endl; if(ptr == 0){ std::cout << "insert in FRONT: ptr =>" << ptr << " value =>" << value << std::endl; front(value); return; } if(ptr == _at_end){ _at_end = new NODE(value,ptr); up_size(); return; } new NODE(value,ptr); up_size(); }
template inline void LIST::insert(unk value){ if(_at_end == 0){ front(value); return; } NODE * new_item = new NODE(value, _at_end); _at_end = new_item; up_size(); }
template inline void LIST::up_size(){ ++_size; }
template inline void LIST::down_size(){ --_size; }
template inline void LIST::front(unk value){ NODE *tmp; up_size(); if(_at_front){ tmp = _at_front; _at_front = new NODE(value); _at_front->next(tmp); return; }
_at_end = _at_front = new NODE(value); return; }
template void LIST::display(std::ostream &os){ NODE * tmp = _at_front;
if (tmp == 0){ os << "No List" << std::endl; return; }
//unk i =0; while(tmp != _at_end){ //std::cout << "Entering While Loop: "<< ++i << std::endl; os << tmp->value() << ":"; tmp = tmp->next(); }
os << tmp->value() << std::endl;
}
template NODE::~NODE(){ //std::cout << "List Item Destroyed" << std::endl; }
template void LIST::remove_front(){ if(_at_front == 0){ std::cout << "No List" << std::endl; return; } NODE * tmp = _at_front; down_size(); _at_front = tmp->next(); if(tmp->next() == NULL) _at_end = 0; //need to clear _at_end as well once you delete the last node delete tmp; return; }
template void LIST::remove_all(){ std::cout << "********CLEANING OUT LIST*********" << std::endl;
while(_at_front){ // std::cout << "***node to remove***\nNode==> " << _at_front << "\tValue==> " << _at_front->value() << std::endl; remove_front(); // std::cout << "Done with remove_all\n"; } }
template NODE * LIST::find(unk search){ NODE * index; if(_at_front == NULL) return NULL; index = _at_front; while(index){ if( search == index->value()) return index; index= index->next(); } return NULL; }
template NODE * LIST::find_all(unk search, NODE * last){
//find_all returns a NULL when it reaches the end of a list and the search node is not found //find_all starts a fresh search from the beginning of a list if a Null is sent as a node value //except for the NULL node, it begins searching with the NEXT node after the one sent to it (for convience of while loops) // //syntax is find_all(int, LIST *); // // if(last == NULL){ last = find(search); return last; } last = last->next(); //search forward if( last == NULL){ return last;//past the end } // std::cout << "Not NULL: Last ==>" << last << " last_value()==> "<< last->value() << " Search==>" << search << std::endl; while( last->value() != search){ if (last == _at_end) return last->next(); last = last->next(); } return last;
//if(last == _at_end){ // std::cout << "found end node. last=> " << last << " value=>" << last->value() << "\n\n"; // std::cout << "last->next()==> " << last->next() << " which is the end and should be null\n"; // return ((last->value() == search) ? last : last->next()); // if(last->value() == search) // return last; // // std::cout << last->next() << " which is the end and should be null\n"; // return last->next(); //which should be null // } //std::cout << "Last ==>" << last << "is not at end==> " << _at_end << " and last value=> " << last->value() << "\n\n"; // return last;
} template void LIST::remove_item(unk search){ NODE* node = find(search); remove_item(node); }
template void LIST::remove_item(NODE * node){ if(node == NULL) return; NODE * prev, *current; if( _at_front == node){ remove_front(); return; } //Walk from the beginning in order to popular prev prev = _at_front; current = prev->next(); while (current != NULL){ if(node == current){ prev->next(current->next()); if(current == _at_end) _at_end=prev; delete current; down_size(); return; } prev = current; current = current->next(); } return; }
template void LIST::sort ( LIST& v ) { const size_t n = v.size();
for (int gap = n/2; 0//cout << " gap==> " << gap << " n ==> " << n << endl; for (int i = gap;i < int(n);i++){ //cout << "i ==> " << i << " gap==> " << gap << " n ==> " << n << endl; for (int j=i-gap;0<=j ;j-=gap ){ //cout << "COMPARE::i ==> " << i << " j==> " << j << " gap==> " << gap << " n ==> " << n << endl; //cout << "***Comparing " << j+gap << " and " << j << endl; if(v[j+gap] T temp = v[j]; v[j] = v[j+gap]; v[j+gap] = temp; } } } } }
}
======================================================================================================
This is the main program with main(){}
======================================================================================================
include "linklist.h" #include #include #include #include #include #include #include
/* * ===================================================================================== * Class: MESSAGE * Description: Messages from Mail Database * ===================================================================================== */
class MESSAGE { friend std::ostream & operator<<(std::ostream &, const MESSAGE&); public: /* ==================== LIFECYCLE ======================================= */ inline MESSAGE():id_("blank"), date_("blank"), from_("blank"), subject_("blank"), message_("blank") {} /* constructor */ inline MESSAGE(int a) { if(a != 0) std::cerr << "Failed Construction: Used and interger: Line==> " << __LINE__ << std::endl;
} /* constructor */ inline MESSAGE(std::string a,std::string b,std::string c,std::string d,std::string e):id_(a), date_(b), from_(c), subject_(d), message_(e) {} /* constructor */
/* ==================== ACCESSORS ======================================= */ inline const std::string& id() const { return id_;} inline const std::string& date() const { return date_;} inline const std::string& from() const { return from_;} inline const std::string& subject() const { return subject_;} inline const std::string& message() const { return message_;}
inline void id(std::string &par ){id_ = par;} inline void date(std::string &par){ date_ = par;} inline void from(std::string &par){ from_= par;} inline void subject(std::string &par){ subject_ = par;} inline void message(std::string &par){ message_ = par;}
/* ==================== MUTATORS ======================================= */
/* ==================== OPERATORS ======================================= */ MESSAGE operator()(std::string a, std::string b, std::string c, std::string d, std::string e){ //This is NOT a CONSTRUCTOR id(a); date(b); from(c); subject(d); message(e); return *this; } bool operator<(MESSAGE const val2){ if(this->subject() < val2.subject()) { return true; } else{ return false ; } }
protected: /* ==================== DATA MEMBERS ======================================= */
private: /* ==================== DATA MEMBERS ======================================= */ std::string id_; std::string date_; std::string from_; std::string subject_; std::string message_;
}; /* ----- end of class MESSAGE ----- */
std::ostream & operator<<(std::ostream& outbound, const MESSAGE& mes){ outbound << "ID ==> " << mes.id() << std::endl << "Date==> " << mes.date() << std::endl<< "From==> " << mes.from() << std::endl << "Subject==> " << mes.subject()<< std::endl << mes.message() << std::endl; return outbound; }
int main(int argv, char **argc){
if(1){ //create a scope to trigger destructors CHAINLIST::LIST mylist; mylist.display(); // int size = mylist.size(); std::cout << "Size of the List at the start is: " << mylist.size() << std::endl; mylist.display(); mylist.insert(1); std::cout << "Size of the List is: " << mylist.size() << std::endl; mylist.display(); mylist.insert(1); std::cout << "Size of the List is: " << mylist.size() << std::endl; mylist.display(); mylist.insert(2); std::cout << "Size of the List is: " << mylist.size() << std::endl; mylist.display(); mylist.insert(4); std::cout << "Size of the List is: " << mylist.size() << std::endl; mylist.display(); mylist.insert(8); std::cout << "Size of the List is: " << mylist.size() << std::endl; mylist.display(); mylist.insert(16); std::cout << "Size of the List is: " << mylist.size() << std::endl; mylist.display(); mylist.remove_front(); std::cout << "Size of the List is: " << mylist.size() << std::endl; mylist.display(); mylist.remove_all(); std::cout << "Size of the List is: " << mylist.size() << std::endl; mylist.display();
std::cout << "****Testing find****" << std::endl;
int a = 0; int b = 1;int c;int index = 0; const int max = 50000; mylist.insert(b); std::cout << "Max Int is ==>" << INT_MAX << std::endl; for(c=b+a;c < INT_MAX ; index++){ mylist.insert(c); a = b; b=c; c=b+a; if(c < b){ mylist.insert(b); break; //This only happens when we get larger than an int } std::cout << "Size of the List is: " << mylist.size() << std::endl; std::cout << "Index 4 is ==> " << mylist[4] << std::endl; std::cout << "Index 3 is ==> " << mylist[3] << std::endl; std::cout << "Index 500000 is ==> " << mylist[500000] << std::endl;
mylist.display(); }
CHAINLIST::NODE * found = mylist.find(1836311903); if(found != NULL) std::cout << "Found ==>" << found->value() << " at " << found << std::endl; else std::cout << "1597 not found\n"; found = mylist.find(23); if(found != NULL) std::cout << "Found ==>" << found->value() << " at " << found << std::endl; else std::cout << "23 not found\n"; std::cout << "int b is ==>" << b << std::endl; for (index = 0; index < max; index++){ found=mylist.find(index); if(found != NULL) std::cout << "Found ==>" << found->value() << " at " << found << std::endl; //else // cerr << index << " not found\n"; if (index > b) break; } mylist.remove_all();
std::cout << "*********** Test find_all ******************" << std::endl; std::cout << "Create a huge link list of random numbers between 1-100\n"; int ran; srand(12345); for (index = 0; index < 50; index++){ ran = rand(); ran = ran % 101; mylist.insert(ran); // std::cout << "random ==>" << ran << std::endl; } mylist.insert(48); mylist.insert(48); mylist.insert(0); mylist.insert(2); mylist.insert(4); mylist.insert(48); mylist.insert(48); mylist.insert(5); mylist.insert(5); mylist.insert(6); mylist.insert(7); mylist.insert(3); mylist.insert(8); mylist.insert(48); mylist.insert(3); mylist.insert(3); mylist.insert(3); mylist.insert(4); mylist.insert(5); mylist.insert(46); mylist.insert(2); mylist.insert(6); mylist.insert(48);
std::cout << "List Size ==>" << mylist.size() << std::endl; int cont48 = 0; CHAINLIST::NODE * tmp = mylist.find_all(48); while(tmp != NULL){ //std::cout << "Found " << tmp->value() << " at ==>" << tmp << std::endl; tmp = mylist.find_all(48, tmp); cont48++; }
std::cout << "******TESTING removing of an item****************" << std::endl; std::cout << "Size is ==>" << mylist.size() << std::endl; std::cout << "48 is in this list " << cont48 << " times\n"; // mylist.display(); tmp = mylist.find_all(48); CHAINLIST::NODE * tmp2 = tmp; while(( tmp=mylist.find_all(48,tmp))){ // std::cout << "while::tmp not NULL\n"; // std::cout << "DELETING ==>" << tmp2 << " VALUE==> " << tmp->value() << std::endl; mylist.remove_item(tmp2); // std::cout << "Node is ==>" << tmp << std::endl; tmp2 = tmp; } mylist.remove_item(tmp2); // mylist.display(); std::cout << "Size is ==>" <// mylist.remove_all(); std::cout << "size + deletes = " << (mylist.size() + cont48) << std::endl;
std::cout << "*************TESTING SOME INSERTS********************************" << __LINE__ << std::endl; mylist.insert(NULL,23); mylist.insert(NULL,23); mylist.insert(NULL,23); // mylist.display(); //std::cout << "*************TESTING SOME INSERTS********************************" << __LINE__ << std::endl; mylist.insert(23); mylist.insert(23); mylist.insert(23); mylist.display(); //std::cout << "*************TESTING SOME INSERTS********************************" << __LINE__ << std::endl; tmp = mylist.find(23); std::cout << "*************found********************************" << __LINE__ << std::endl; //std::cout << tmp << "\t" << tmp->value() << "*************TESTING SOME INSERTS********************************" << __LINE__ << std::endl; mylist.insert(tmp,1111); //std::cout << "*************TESTING SOME INSERTS********************************" << __LINE__ << std::endl; // mylist.display(); tmp = mylist.find_all(23,tmp); //std::cout << "*************found********************************" << __LINE__ << std::endl; //std::cout << tmp << "\t" << tmp->value() << "*************TESTING SOME INSERTS********************************" << __LINE__ << std::endl; mylist.insert(tmp,1111); //std::cout << "*************TESTING SOME INSERTS********************************" << __LINE__ << std::endl; // mylist.display(); while((tmp = mylist.find_all(23, tmp))){ //std::cout << "*************found********************************" << __LINE__ << std::endl; //std::cout << tmp << "\t" << tmp->value() << "*************TESTING SOME INSERTS********************************" << __LINE__ << std::endl; mylist.insert(tmp,1111); //std::cout << tmp << "\t" << tmp->value() << "*************TESTING SOME INSERTS********************************" << __LINE__ << std::endl; }
while((tmp = mylist.find_all(23, tmp))){ std::cout << "tmp==> "<< tmp << "\t" << "tmp-value()" << tmp->value() << std::endl; std::cout << "*************WHile Loop TESTING SOME INSERTS findall********************************\n"; std::cout << tmp->value() << "\t" << (tmp->next())->value() << std::endl; }
tmp=NULL; while((tmp = mylist.find_all(1111, tmp))){ std::cout << "tmp==> "<< tmp << "\t" << "tmp-value()" << tmp->value() << std::endl; // std::cout << "*************While Loop findall********************************\n"; std::cout << tmp->value() << "\t" << (tmp->next())->value() << std::endl; } mylist.display();
tmp=NULL; mylist.insert(tmp,8888); mylist.insert(8888); std::cout << "inserted\n\n\n"; mylist.display(); while((tmp = mylist.find_all(8888, tmp))){ // std::cout << "tmp==> "<< tmp << "\t" << "tmp-value() " << tmp->value() << std::endl; // std::cout << "*************While Loop TESTING findall********************************\n"; std::cout << tmp->value() << "\t" << (tmp->next())->value() << std::endl; } mylist.display();
}//End of Scope - Watch for the Destructors
CHAINLIST::LIST * mylist = new CHAINLIST::LIST; mylist->display(); mylist->size(); CHAINLIST::LIST * mylist2 = new CHAINLIST::LIST; mylist2->insert("Hello World"); mylist2->insert("I love Schmueli Bear"); mylist2->insert("Francine Robin is great"); mylist2->insert("Life is wonderful"); mylist2->insert("Shani is a superstar"); mylist2->insert("Aviva is the blondie girl"); mylist2->insert("C++ is EASY!!"); mylist2->insert("What?"); mylist2->insert("Taly is my big girl"); mylist2->insert("Dovid Shimon is the MAN"); mylist2->insert("Hernandez laces a long line drive.."); mylist2->insert("Lets Go Mets"); mylist2->display(); std::cout << "Number of Strings is ==> "<< mylist2->size() << std::endl; CHAINLIST::NODE * found = mylist2->find("Lets Go Mets"); std::cout << "We Found " << found << " ==>" << found->value() << std::endl; mylist2->sort(*mylist2); std::cout << "Number of Strings after sort is ==> "<< mylist2->size();
found = mylist2->find("Lets Go Mets"); std::cout << "We Found " << found << " ==>" << found->value() << std::endl;
mysqlpp:: Connection handle("rubenmail", 0, "ruben", "************************"); if( handle.connected() ){ std::cout << "connected\n"; }else{ std::cout << "no Connection: " << handle.error() << std::endl; return 1; }
mysqlpp::Query ask(&handle,true, "select id, day, fromit, subject, message from postings where fromit like \"%francal%\""); mysqlpp::Query ask2(&handle,true, "select id, day, fromit, subject, message from postings where fromit like \"%2013156062%\""); mysqlpp::StoreQueryResult::const_iterator place; mysqlpp::Row row; mysqlpp::StoreQueryResult fran; mysqlpp::StoreQueryResult fran_text; if((fran = ask.store()) && (fran_text = ask2.store())){
MESSAGE * onemail = new MESSAGE(); //std::cout << onemail->id() << onemail->date() << onemail->from() << onemail->subject() << onemail->message() << std::endl; //MESSAGE * twomail = new MESSAGE("Oh ", "Hello ", "DOLLY. ", "Oh ", "Hello"); //std::cout << twomail->id() << twomail->date() << twomail->from() << twomail->subject() << twomail->message() << std::endl; //(*onemail)("Oh ", "Hello ", "DOLLY. ", " I'm all alone", " We Code for Food"); //std::cout << onemail->id() << onemail->date() << onemail->from() << onemail->subject() << onemail->message() << std::endl; CHAINLIST::LIST mylist3; for(place = fran.begin(); place != fran.end(); ++place){ row = *place; //std::cout << "\t" << row[0] << "\t" << row[1] << "\t" << row[2] <<"\t" << row[3] <<"\t" << std::endl; std::cout << "Got this far " << __LINE__ << std::endl; //std::string tmp = row[0].c_str(); //std::cout << tmp << std::cout; (*onemail)(row[0].c_str(), row[1].c_str(), row[2].c_str(),row[3].c_str(),row[4].c_str()); mylist3.insert(*onemail); } for(place = fran.begin();place != fran.end(); ++place){ row = *place; mylist3.insert((*onemail)(row[0].c_str(),row[1].c_str(),row[2].c_str(),row[3].c_str(),row[4].c_str())); }
mylist3.display(); std::cout << "Number of Messages is ==> "<< mylist3.size(); mylist3.sort(mylist3); std::cout << "Number of Messages after sort is ==> "<< mylist3.size(); std::cout << "Sorted Order By Subject **************************************************************************" << std::endl; mylist3.display();
}
return 0; }
========================================================================================================================
The problem is when I try to return NULLS or Zeros from accessory methods, especially with the operator[] overload in templates of the type message. These are needed because the end of the linked list is marked with zero values. First I was returning 0's.
The reference returns in operator[] didn't like that saying they were Temporary objects when returned by NODE.value(). So I added a NODE.value_ref(). But when the template class type is std::string and i try to return 0, it says that class string is not able to determine which operator= to use
I tried to add an unk err member, but I can't initializing it according to C++ iso standard, and it is still ambigious to to string class when I try to assign it.
I'm just frustrated to no end at this point and need advise as to how to code this rationally.
Ruben
-- http://www.mrbrklyn.com - Interesting Stuff http://www.nylxs.com - Leadership Development in Free Software
So many immigrant groups have swept through our town that Brooklyn, like Atlantis, reaches mythological proportions in the mind of the world - RI Safir 1998
http://fairuse.nylxs.com DRM is THEFT - We are the STAKEHOLDERS - RI Safir 2002
"Yeah - I write Free Software...so SUE ME"
"The tremendous problem we face is that we are becoming sharecroppers to our own cultural heritage -- we need the ability to participate in our own society."
"> I'm an engineer. I choose the best tool for the job, politics be damned.< You must be a stupid engineer then, because politcs and technology have been attached at the hip since the 1st dynasty in Ancient Egypt. I guess you missed that one."
? Copyright for the Digital Millennium
|
|