ОС: WindowsXP(Win32) Комипилятор: GCC IDE: Eclipse CDT
Постановка: Класс строк без использования std::string & std::vector и прочего
Что случилось?: Косяки с памятью и иногда Exception Error
Что делал?: Исключил возможные варианты до 1 строки!
Где ловишь?: Всё работает нормально до передачи в функцию, более того если передовать менее n раз то проблемы не возникает!!!
Где код?:
Код | #ifndef MI_String_Lib #define MI_String_Lib
class StringC { public: //Де/Конструкторы StringC():Length(0)//Пустой конструктор, ложим с строку пустоту { Allocate(); }
StringC(char *Line)//Передача строки символов { Assign(Line); }
StringC(const StringC& String)//Конструктор копирования { Assign(String); }
~StringC(void)//Деструктор удаляющий массив символов Tape { Free();//ЕСЛИ УБРАТЬ ТО ВСЁ РАБОТАЕТ!!! ПОЧЕМУ??? }
//Интерфейсные методы int GetLength(void) { return Length; }
char *Return(void) { return Tape; }
char Return(int Position) { if(Position>0&&Position<=Length) return Tape[Position-1]; else return '\0'; }
//Перегруженные операторы void operator =(char *Line){Assign(Line);} void operator =(const StringC& String){Assign(String);}
protected: void Assign(char *Line) { if(Tape!=Line)//Проверка на String=String.Return(); { for(Length=0;Line[Length];Length++);//Подсчёт длинны переданной строки Free();//Освобождение текущего массива символов Allocate();//Выделение памяти под новый for(int I(0);I<Length;I++) Tape[I]=Line[I];//Посимвольное перекладывание } else return; }
void Assign(const StringC& String) ЕСЛИ УБРАТЬ ТО ТОЖЕ ВСЁ РАБОТАЕТ!!! ПОЧЕМУ??? { if(Tape!=String.Tape)//Проверка на String=String; { Length=String.Length;//Метод GetLength не даёт использовать, незнаю почему но так работает Free();//Освобождение текущего массива символов Allocate();//Выделение памяти под новый for(int I(0);I<Length;I++)Tape[I]=String.Tape[I];//Посимвольное перекладывание } else return; }
void Allocate(void) { if(!Length) Length=1; Tape=new char[Length+1]; Tape[Length]='\0'; } void Free(void) { delete[] Tape;//суть проблемы не меняется от delete Tape; }
char *Tape;//Указатель на массив символов int Length;//Длинна };
#endif
|
Комуто может так будет удобнее:
Код | class StringC { public: //Де/Конструкторы StringC():Length(0){Allocate();} StringC(char *Line){Assign(Line);} StringC(const StringC& String){Assign(String);} ~StringC(void){Free();} //Интерфейсные методы int GetLength(void){return Length;} char *Return(void){return Tape;} char Return(int Position){if(Position>0&&Position<=Length) return Tape[Position-1];else return '\0';} //Перегруженные операторы void operator =(char *Line){Assign(Line);} void operator =(const StringC& String){Assign(String);}
protected: void Assign(char *Line) { if(Tape!=Line) { for(Length=0;Line[Length];Length++); Free();Allocate(); for(int I(0);I<Length;I++) Tape[I]=Line[I]; } else return; } void Assign(const StringC& String) { if(Tape!=String.Tape) { Length=String.Length; Free();Allocate(); for(int I(0);I<Length;I++)Tape[I]=String.Tape[I]; } else return; } void Allocate(void) { if(!Length) Length=1; Tape=new char[Length+1]; Tape[Length]='\0'; } void Free(void){delete[] Tape;} char *Tape; int Length; };
|
Ситуация для возникновения ошибки:
Код | void S(StringC Data) { /*StringC Ya;//Иногда Ya=Data;*/ cout << Data.Return(); }
void main(void) { StringC A("Mage"); S(A);//При сокращении до 2 передач, всё работает тоже! S(A); S(A); S(A); S(A); S(A); S(A); S(A); cout << "Ok";
|
Мои соображения: Ошибки невозникает при аналогичной простой цепочки присваиваний, только при передаче в функцию, логично предположить что проблема с преждевременным удалением локального элемента, но такового не наблюдал
Очень прошу чего-нибудь посоветовать КРОМЕ как: 1)Использовать std::string 2)Забить на деструктор и на мегобайты памяти. Непойдёт, нужна стабильность, т.к для реального использования, не для школьного задания и т.д |