Wprowadzam podwójnie połączoną listę typów sortów, która przechowuje "wiadra" (węzły), z których każda zawiera predefiniowaną liczbę znaków. Każde wiadro przechowuje wskaźnik do następnego i poprzedniego segmentu, a klasa listy (BucketString) przechowuje wskaźnik do nagłówka Bucket. Mam kompilacji za pomocą g ++, który zgłasza błądC++: zakończenie wywoływane po rzuceniu instancji 'std :: bad_alloc'
terminate called after throwing an instance of 'std::bad_alloc'
what(): std::bad_alloc
make: *** [run] Aborted (core dumped)
ilekroć uruchomić kod i dodać ciąg znaków do listy, używając następującej dodać metodę, która jest zawarta w mojej klasie wiadro, i nazywa się od wymieniaj własne metody klasy w razie potrzeby.
Kod:
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;
}
Gdy zostanie zgłoszony błąd, metoda add jest wywoływana z „listy” członek klasy metody append, która działa w następujący sposób:
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
}
pliku nagłówka dla klasy kubełków jest:
#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
Witaj w SO, ale pozwól, że zapytam: co próbujesz? Czy dodałeś instrukcje drukowania, aby zobaczyć, skąd pochodzi błąd? Czy użyłeś debuggera? (I nie, kod, który pokazałeś, nie wystarcza) –
Dodałem wspomniane instrukcje drukowania, w ten sposób wiem, że są zgłaszane, gdy ta metoda jest wywoływana. Dziwne jest to, że metoda wydaje się działać poprawnie dla pierwszych 70 lub więcej znaków dodanych, ale wtedy wiadomość jest wyrzucana. Co jeszcze chcesz? Niestety, klasa 'list' jest dość długa, uwzględnię tę metodę w klasie 'list' (zwanej BucketString), która wywołuje tę metodę, jeśli to trochę pomaga. – wesrobin
bad_alloc jest zgłaszane przez operatora new, gdy brakuje pamięci. Ponieważ add używa rekursji, być może rekursje wymykają się z pamięci. – engineerC