2013-03-27 8 views
7

私は、あらかじめ定義された文字数を含むバケット(ノード)を格納する2重リンクリストクラスを実装しています。各バケットは、次のバケットおよび前のバケットへのポインタを格納し、リストクラス(BucketString)は、先頭のバケットへのポインタを格納します。私は、コードを実行すると、次は私のバケットクラス内に含まれている方法を、追加使用して、リストに文字列を追加し、から呼び出されたとき、私はエラーC++: 'std :: bad_alloc'のインスタンスをスローした後に呼び出されます。

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

をスローグラムを++使用してコンパイルしています必要に応じてクラスのメソッドをリストします。

コード:

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; 
} 

エラーがスローされた場合、Addメソッドは次のように動作する「リスト」クラスのメンバメソッドはappend、から呼び出されている:

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 
} 

ヘッダファイルバケットクラスの場合:

#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's 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 
+1

ようこそ、私に聞かせてください:あなたは何を試しましたか? print-statementsを追加して、エラーの原因を調べましたか?あなたはデバッガを使いましたか? (そして、あなたが示したコードは十分ではありません) –

+0

私は上記のprint文を追加しました。これは、このメソッドが呼び出されたときにスローされていることを知る方法です。奇妙なことに、このメソッドは、最初の70文字ほど追加された文字に対して正しく動作するように見えますが、その後メッセージがスローされます。あなたはもっと何を望みますか?残念ながら、 'list'クラスはかなり長く、このメソッドを呼び出す 'list'クラス(BucketStringと呼ばれる)にメソッドを含めることになります。 – wesrobin

+0

bad_allocは、メモリ不足時に演算子newによってスローされます。 addは再帰を使用するので、おそらくメモリから自分自身を再帰的に取り出すことになります。 – engineerC

答えて

5

これは動作します:私のBucket(std::size_t bucketSizeB)コンストラクタでstrのイニシャライザは、str(new char[bucketSizeB]からstr(new char[bucketSizeB_])に変更する必要があります(つまり、cos bucketSizeB変数を使用する代わりにntructorを使用します)。

+0

メンバーは宣言された順序で初期化されるためです。コンパイラの設定が十分に高い場合は、警告が表示されます。 – GManNickG

+1

@GManNickG、なぜ彼の特定のエラーの警告を受けるだろうか分からない。 'bucketSizeB'変数は先にグローバルとして定義されていました... –

5

1)try/catchブロックでの終了を防ぐことができます。

2)プログラムを実行したときに発生しているようです。また、 "make"がプログラムを自動的に実行するようにも聞こえます。正しい?

3)そうであれば、デバッガを見て、クラッシュしている正確な行を特定する必要があります。

4)「diff」、「bucketSizeB」、「filled」のうちの1つ以上が非常に大きく(または負に)なることがわかります。どちらがバグでしょう:)あなたは簡単に修正することができます - 一度それを見つける。それはあなたのための便利なデバッガであることを起こる場合

5)ここのは、GDBの良いチュートリアルです:

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

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

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

+0

1)エラーを隠し、状況を悪化させ、問題を解決しません。 2)は無関係です。 3)はコメントでなければなりません。 –

関連する問題