C ++: ending the call after calling the instance of 'std :: bad_alloc'

I am implementing a double-join class that stores "buckets" (nodes), each of which contains a predetermined number of characters. Each bucket stores a pointer to the next and previous bucket, and the list class (BucketString) stores a pointer to the head bucket. I am compiling with g ++ that throws an error

terminate called after throwing an instance of 'std::bad_alloc' what(): std::bad_alloc make: *** [run] Aborted (core dumped) 

whenever I run the code and add a character string to the list using the following add method, which is contained in my bucket class, and if necessary is called from the list boxโ€™s own methods.

the code:

 std::size_t bucketSizeB; int filled; char* str; Bucket* next; Bucket* prev; Bucket::Bucket() : bucketSizeB(7), str(new char[7]), next(NULL), prev(NULL), filled(0) {} Bucket::Bucket(std::size_t bucketSizeB_) : bucketSizeB(bucketSizeB_), str(new char[bucketSizeB]), next(NULL), prev (NULL), filled(0) {} Bucket::Bucket(const Bucket& rhs) : bucketSizeB(rhs.bucketSizeB), next(rhs.next), prev(rhs.prev), filled(rhs.filled) { for (int i = 0 ; i < (int) bucketSizeB ; i++) { str[i] = rhs.str[i]; } } void Bucket::add(std::string line) { int diff = bucketSizeB - filled; //if the bucket is already partially filled std::string tmp = line.substr(0, diff); for (std::size_t i = 0 ; i < tmp.length() ; i++) { str[filled] = line[i]; ++filled; } if (line.length() > bucketSizeB) { next = new Bucket(bucketSizeB); next->prev = this; next->add(line.substr(diff, line.length()-diff)); } } Bucket::~Bucket() { if (prev) { if (next) { prev->next = next; } else { prev->next = NULL; } } if (next) { if (prev) { next->prev = prev; } else { next->prev = NULL; } } delete [] Bucket::str; } 

When an error occurs, the add method is called from the member 'list' method, which works as follows:

 void BucketString::append (std::string& line) { length += line.length(); //Just a way to store the length of the string stored in this BucketString object if (!head) //If the head node pointer is currently null, create a new head pointer { head = new Bucket(bucketSize); } Bucket* tmp = head; while (tmp->next) //Finds the tail node { tmp = tmp->next; } tmp->add(line); //Calls the Bucket add function on the tail node } 

Header file for bucket class:

 #include <cstddef> #include <string> #include <iostream> #ifndef BUCKET_H_ #define BUCKET_H_ namespace RBNWES001 { class Bucket { public: //Special members and overloaded constructor Bucket(void); Bucket(std::size_t); Bucket(const Bucket&); ~Bucket(); //Copy Assignment not included because it not needed, I'm the only one who is gonna use this code! :) //Add method void add(std::string); int filled; char* str; Bucket* next; Bucket* prev; std::size_t bucketSizeB; }; } #endif 
+7
source share
2 answers

This works: in my Bucket(std::size_t bucketSizeB) constructor Bucket(std::size_t bucketSizeB) initializer for str should change from str(new char[bucketSizeB] to str(new char[bucketSizeB_]) (i.e. use the argument passed to cosntructor instead of using a variable bucketSizeB).

+5
source

1) You can prevent completion with a try / catch block.

2) It seems that this happens when the program is executed. It also sounds like "make" executes a program automatically. Correctly?

3) If so, you want to look in the debugger and determine the exact line where it crashes.

4) I suspect that if you trace the code, you will see that one or more of the "diff", "bucketSizeB" and / or "filled" become very large (or negative). Which would be a mistake :) Which you can easily fix - as soon as you find it.

5) Here are some good GDB guides if it is a debugger convenient for you:

http://dirac.org/linux/gdb/

http://www.cs.cmu.edu/~gilpin/tutorial/

http://www.cprogramming.com/gdbtutorial.html

+5
source

All Articles