0

This is the error message in question: terminate called after throwing an instance of 'std::length_error' what(): basic_string::_S_create Aborted

This is the code that triggers it. This section in the main.cpp file:

  case '-':   // DeleteItem
              try
              {
                int id;
                inputs >> id;
                Student s(id, "NULL", "NULL");
                cout << "DeleteItem('" << id << "') -- ";
                s = tPtr->DeleteItem(s);
                cout << "Deleted  ";
                s.Print();
              }

It never gets past tPtr->DeleteItem(s), and this is the code involved for DeleteItem(s). DeleteItem function:

      template <typename SomeType>
      SomeType BSTree<SomeType>::DeleteItem(SomeType item){
      if (rootPtr == NULL){
      throw EmptyBSTree();
      }
      Delete(rootPtr, item);
      cout<<"done"<<endl;
      } 

Delete function:

template <typename SomeType>
void BSTree<SomeType>::Delete(BSTreeNode<SomeType>*& treePtr, SomeType& item){


if (treePtr->data == item){

DeleteNode(treePtr);
cout<<"done2"<<endl;
}
else{

if (item<treePtr->data){

if (treePtr->leftPtr != NULL){
Delete(treePtr->leftPtr, item);
}

else{
throw NotFoundBSTree();
}
}
else{
if (treePtr->rightPtr != NULL){
Delete(treePtr->rightPtr, item);
}

else{
throw NotFoundBSTree();
}
}
}

DeleteNode function:

template <typename SomeType>
void BSTree<SomeType>::DeleteNode(BSTreeNode<SomeType>*& treePtr){
cout<<"here"<<endl;
BSTreeNode<SomeType>* temp = new BSTreeNode<SomeType>;
temp = treePtr;
if (treePtr->leftPtr == NULL && treePtr->rightPtr == NULL){


delete temp;

}
else{

if (treePtr->leftPtr == NULL){
treePtr = treePtr->rightPtr;
delete temp;
}

else if (treePtr->rightPtr == NULL){
treePtr = treePtr->leftPtr;
delete temp;
}

else{
treePtr->data = GetPredecessor(treePtr->leftPtr);
Delete(treePtr->leftPtr,treePtr->data);
}
}
cout<<"I am here"<<endl;
}

I find this very strange as all cout statements I put to make sure the code gets to that line are all outputted to the terminal, so it exits both functions, but it never gets past the original line in main.cpp. I'm super confused on why I keep getting that error.

EDIT: This problem was solved by adding a return to DeleteItem. However I ran into another problem. Delete doesn't seem to work here:

template <typename SomeType>
void BSTree<SomeType>::DeleteNode(BSTreeNode<SomeType>*& treePtr){
BSTreeNode<SomeType>* temp;
temp = treePtr;
if (treePtr->leftPtr == NULL && treePtr->rightPtr == NULL){
delete temp;
cout<<"This is "<<treePtr->data<<endl;
}
else{
if (treePtr->leftPtr == NULL){
treePtr = treePtr->rightPtr;
delete temp;
}

else if (treePtr->rightPtr == NULL){
treePtr = treePtr->leftPtr;
delete temp;
}

else{
treePtr->data = GetPredecessor(treePtr->leftPtr);
Delete(treePtr->leftPtr,treePtr->data);
}
}

}

Tree Ptr should be deleted but it prints out This is (random number). Why?

RogueNin7x
  • 37
  • 4
  • 1
    It looks like you need a return statement in `BSTree::DeleteItem`. – Nathan Pierson Nov 13 '20 at 23:59
  • Turn on your compiler warnings. Compilers will gladly warn about missing return statements. – chris Nov 14 '20 at 00:08
  • @chris how do I do that? I'm on a remote linux server but I might be on it for a while so I'd prefer to – RogueNin7x Nov 14 '20 at 00:16
  • If you execute `man gcc` you will get a comprehensible list of all compilation options, including the one you are looking for. Are you familiar with the `man` command, and what it does? – Sam Varshavchik Nov 14 '20 at 00:18
  • Not quite but I'll read up on it! – RogueNin7x Nov 14 '20 at 00:24
  • @SamVarshavchik I added a second part that doesn't work and is confusing, could you look at it and tell me what's wrong? – RogueNin7x Nov 14 '20 at 00:47
  • An [mre] is needed for others to debug this, but you'll be glad to hear you don't need my help to figure this out, just a tool you already have: your debugger! This is exactly what a debugger is for. It runs your code one line at a time, and shows you what it does. Being able to use a debugger is a required skill for every C++ developer, no exceptions. With your debugger's help you should be able to find all problems in this and all future programs you write, without having to ask anyone for help. Have you tried using your debugger, already? If not, why not? What did your debugger show you? – Sam Varshavchik Nov 14 '20 at 00:52
  • @SamVarshavchik I'm very familiar with debuggers using visual studio, but I'm doing a school project on a remote linux server and I'm not sure we have a debugger as our professor asked us to use cout statements to debug. If I could somehow transfer my code to visual studio to debug that would be amazing. – RogueNin7x Nov 14 '20 at 00:58
  • Linux servers should have gdb. I debug remotely all the time. – Sam Varshavchik Nov 14 '20 at 01:00
  • @RogueNin7x For information on enabling warnings, see [Why should I always enable compiler warnings?](https://stackoverflow.com/questions/57842756/why-should-i-always-enable-compiler-warnings) – JaMiT Nov 14 '20 at 01:58
  • Given linux, I recommend at least `-Wall -Wextra -pedantic` for warning options. There are useful warnings not included in that, but it's a great start. The compiler will solve a lot of problems before you see them. (Also, VS does technically support remote linux debugging, but I haven't personally used it so I can't say how easy it is to get going. Learning how to use raw gdb is useful, though I wouldn't put it high on the priority list when starting out.) – chris Nov 14 '20 at 02:00
  • @RogueNin7x In the absence of a debugger, diagnostic messages to `cout` or `cerr` can be used (preferably `cerr` since it is not buffered). It's more time-intensive, but works. If you find that you double the size of your code -- by putting a `cerr` diagnostic after every line -- you're not necessarily doing too much. – JaMiT Nov 14 '20 at 02:01

0 Answers0