1

Currently I'm trying to set up a member function for Student that reads a string from cin, is used as an argument for this function and then creates a Student object with the data. However, is it giving me a bad_alloc error. I know the function is getting the string but it gives this error after the new object is created.

Error:

./a.out

Please insert name for student:
Bob_Russel
terminate called after throwing an instance of 'std::bad_alloc'
  what():  std::bad_alloc
Aborted

Constructor:

Student::Student(string tname){

  name = tname;

}

Function:

Student Student::readStudent(istream &i){

  Student *stud;

  string y;

  i >> y;

  stud = new Student(y);

  return  *stud;

}

testStudent.cpp:

 #include "Student.h"

int main(){

  Student *stud3;
  cout << "\nPlease insert name for student:\n";

  stud3->readStudent(cin);


return 0;

}
Mark Berube
  • 206
  • 3
  • 11
  • 8
    `std` isn't a really good variable name. (Unrelated to your issue, but it's confusing.) – Mat Nov 21 '11 at 12:35
  • 1
    creating it on the heap and returning it like that feels like a no-no to me – r_ahlskog Nov 21 '11 at 12:35
  • 7
    The code is nonsensical, but it doesn't contain the error. Work out a **complete, minimal example** that shows your problem and post that. – Kerrek SB Nov 21 '11 at 12:36
  • @user634144 std::bad_alloc is thrown if allocation doesn't succeed [msdn link](http://msdn.microsoft.com/en-us/library/6512dwes%28v=vs.80%29.aspx) . So add statement with new in try block and catch that exception. – Pradeep Nov 21 '11 at 12:39
  • 1
    I suspect an attempt at recursive dynamic allocation. Though I don't understand why you've used `new` here _at all_; do you? – Lightness Races in Orbit Nov 21 '11 at 12:40
  • 1
    The code leaks memory. Whether that is the cause only you can figure out, since only you know who calls what function with what parameters and input how often. Also you should use a debugger to figure out where exactly the exception gets thrown. – PlasmaHH Nov 21 '11 at 13:00

3 Answers3

7

Not only does the code leak memory (creating a new Student in readStudent that is never deleted), in main you are using an uninitialized pointer to call readStudent. Possibly this is corrupting your heap such that the call to new throws a std::bad_alloc.

Take another look at C++ memory management and object lifetimes. There is really no need to use pointers at all here. As a starting point, your main could be modified to this:

int main() {
    Student stud3;
    std::cout << "Please insert name for student:" << std::endl;
    stud3.readStudent(std::cin);
}

It would perhaps also be better if you read in the name within main (as a std::string), and then pass the name directly to the Student constructor:

int main() {
    std::cout << "Please insert name for student:" << std::endl;
    // Read in the name.
    std::string name;
    std::cin >> name;
    // Create the student with the input name.
    Student stud3(name);
 }
zennehoy
  • 6,405
  • 28
  • 55
  • Alternatively, have another constructor that takes in the IOStream as input. But yes, zennehoy is right here. – dyoo Sep 20 '12 at 23:16
1

It looks like you're trying to implement a factory method. If that's the case, then you're missing the static keyword and the correct syntax for the readStudent call.

class Student{
public:
    Student(std::string tname);
    static Student* readStudent(std::istream &i);
private:
    std::string name
};

Student::Student(std::string tname) {
    name = tname;
}

Student* Student::readStudent(std::istream &i){
    std::string y;
    i >> y;
    return new Student(y);
}

int main(int argc, char* argv[]){
    Student *stud3 = NULL;

    std::cout << "\nPlease insert name for student:\n";

    stud3 = Student::readStudent(cin);

    return 0;
}
Annirak
  • 11
  • 1
-1

You are allocating on the heap using new and never freeing it, thus you run out of memory and get a bad_alloc. For every new there should be a delete.

This will not throw bad_alloc:

Student Student::readStudent(std::istream& i)
{        
   std::string y;    
   i >> y;    
   return Student(y);    
}
ronag
  • 49,529
  • 25
  • 126
  • 221
  • Impossible! This explanation is wrong in the specific details about what's causing the bad_alloc. It is not because the program is running out of memory. Rather, the main function is incorrectly trying to access stud3, and that's pointing to uninitialized memory. – dyoo Sep 20 '12 at 23:15
  • What are you talking about? An access violation does not throw a `bad_alloc` exception. The only thing that can cause a `bad_alloc` is when the system cannot allocate more memory. – ronag Sep 21 '12 at 06:31
  • Also note that the OP edited his question after my answer and added `testStudent.cpp`. Which either way doesn't matter, although stud3 is uninitialized his code will work since he is not accessing any member variables. Not saying he is doing it correctly, just that the problem you are referring to is not relevant to his question about why it can throw `bad_alloc`. – ronag Sep 21 '12 at 06:37