Изучая C #, я находил интересным переопределять такие вещи, как List или LinkedList, просто чтобы понять, как он работает, и возможные проблемы, которые могут возникнуть при его реализации.
Во время изучения C ++, поскольку у меня есть некоторый опыт вВ C # я решил бросить вызов самому себе и попытаться реализовать более продвинутый код, чем то, о чем говорится в конце главы.Итак, я попытался реализовать не универсальный список в C ++, чтобы попробовать его, но в итоге получил очень странную ошибку сегмента.
Небольшой отказ от ответственности в коде, в то время как пытаясь исправить это, я закончилрефакторинг и удаление чего-либо (хотя ни одно из них не изменило ошибку), чтобы одна или две функции не имели смысла, но после нескольких часов попыток понять проблему, я не хочу ничего удалять или изменять и случайно решаю проблему.Во всяком случае, вот код.
class List {
private:
int *ListData;
size_t ListSize;
size_t Pos;
std::stack<size_t> NullList;
size_t InternalNull();
inline size_t PosOnly();
void Check();
size_t (List::*NextNumber)();
public:
List(bool InternalNullHandle);
List(size_t DefaultSize, bool InternalNullHandle);
~List();
void Add(const int SalesRef);
int GetCopy(size_t Pos);
int Get();
};
List::List(bool InternalNullHandle) {
NextNumber = (InternalNullHandle) ? &List::InternalNull : &List::PosOnly;
ListSize = 32;
ListData = new int[32];
Pos = 0;
}
List::List(size_t DefaultSize, bool InternalNullHandle) {
NextNumber = (InternalNullHandle) ? &List::InternalNull : &List::PosOnly;
ListSize = DefaultSize;
ListData = new int[DefaultSize];
Pos = 0;
}
List::~List() {
delete[] ListData;
}
void List::Check() {
if (Pos >= ListSize) {
size_t OldSize = ListSize;
ListSize*=2;
int *Buffer = new int[ListSize];
memcpy(Buffer, ListData, sizeof(int)*OldSize);
if (ListData != NULL) {
delete[] ListData; //POINT OF INTEREST ONE
ListData = NULL;
}
else {
std::cerr<<"ListData is null."<<std::endl;
}
ListData = Buffer;
}
}
size_t List::InternalNull() {
if (NullList.size() != 0) {
size_t ToReturn = NullList.top();
NullList.pop();
return ToReturn;
}
return PosOnly();
}
inline size_t List::PosOnly() {
size_t Old = Pos;
++Pos;
Check();
return Old;
}
inline void List::Add(const int SalesRef) {
//size_t Value = (this->*NextNumber) ();
//ListData[Value] = SalesRef;
//if the above code is utilised instead, everything works fine
ListData[ (this->*NextNumber) () ] = SalesRef; //POINT OF INTEREST TWO
}
inline int List::GetCopy(size_t Pos) {
return ListData[Pos];
}
Я обычно не публикую, но Google широко.В итоге я установил и запустил valgrind, что приводило к ошибкам чтения и записи в точке интереса 1, когда использовалась точка интереса 2.Однако, когда точка интереса два была закомментирована и использовались закомментированные строки, проблем не возникало.
Проблема возникает только после 128 итераций, то есть она корректно удваивается до 64 и 128, а также удаляет массивы.правильно.
Кроме того, как примечание, код отлично работал на Windows, скомпилированной с g ++.
Я попытался воспроизвести ошибку, используя отдельный класс, но он работал отлично.
Опять же, я знаю, что должен использовать стандартные контейнеры (и я буду), но мне нравится все понимать, и тот факт, что я не могу понять это, чрезвычайно раздражает.В сочетании с тем фактом, что я не могу даже воспроизвести его, и мне пришлось скопировать этот неполный и плохо спроектированный код, это только ухудшает ситуацию.Заранее спасибо за помощь!
Незначительное редактирование, если действительно трудно читать, я добавлю комментарии и попытаюсь очистить код, не нарушая (ну, скорее исправляя).ОС, на которых он тестировался, была Windows 7 с mingw (которая работала) и Debian с g ++ (которая работала только с закомментированными строками).