Модераторы: Poseidon
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> [C++]Класс строк без использование библиотек, Наверное теория, странная ошибка 
V
    Опции темы
Centry
  Дата 24.7.2008, 13:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 2
Регистрация: 21.7.2008

Репутация: нет
Всего: нет



ОС: 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)Забить на деструктор и на мегобайты памяти. Непойдёт, нужна стабильность, т.к для реального использования, не для школьного задания и т.д

Это сообщение отредактировал(а) Centry - 24.7.2008, 13:28
PM MAIL   Вверх
vinter
Дата 25.7.2008, 23:10 (ссылка) |  (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Explorer
****


Профиль
Группа: Завсегдатай
Сообщений: 2735
Регистрация: 1.4.2006
Где: Н.Новгород

Репутация: 1
Всего: 56



неправильно написан конструктор копирования, напиши его верно. Он предназначен для копирования, а не для непойми чего.


--------------------
Мой блог
PM MAIL WWW   Вверх
Centry
Дата 5.8.2008, 18:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 2
Регистрация: 21.7.2008

Репутация: нет
Всего: нет



А можно чуть-чуть по подробнее? Вроде ничего криминального не делаю:
-Беру длинну
-Удаляю старый массив
-Создаю новый
-Перекладываю в новый из полученного
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Центр помощи"

ВНИМАНИЕ! Прежде чем создавать темы, или писать сообщения в данный раздел, ознакомьтесь, пожалуйста, с Правилами форума и конкретно этого раздела.
Несоблюдение правил может повлечь за собой самые строгие меры от закрытия/удаления темы до бана пользователя!


  • Название темы должно отражать её суть! (Не следует добавлять туда слова "помогите", "срочно" и т.п.)
  • При создании темы, первым делом в квадратных скобках укажите область, из которой исходит вопрос (язык, дисциплина, диплом). Пример: [C++].
  • В названии темы не нужно указывать происхождение задачи (например "школьная задача", "задача из учебника" и т.п.), не нужно указывать ее сложность ("простая задача", "легкий вопрос" и т.п.). Все это можно писать в тексте самой задачи.
  • Если Вы ошиблись при вводе названия темы, отправьте письмо любому из модераторов раздела (через личные сообщения или report).
  • Для подсветки кода пользуйтесь тегами [code][/code] (выделяйте код и нажимаете на кнопку "Код"). Не забывайте выбирать при этом соответствующий язык.
  • Помните: один топик - один вопрос!
  • В данном разделе запрещено поднимать темы, т.е. при отсутствии ответов на Ваш вопрос добавлять новые ответы к теме, тем самым поднимая тему на верх списка.
  • Если вы хотите, чтобы вашу проблему решили при помощи определенного алгоритма, то не забудьте описать его!
  • Если вопрос решён, то воспользуйтесь ссылкой "Пометить как решённый", которая находится под кнопками создания темы или специальным флажком при ответе.

Более подробно с правилами данного раздела Вы можете ознакомится в этой теме.

Если Вам помогли и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, Poseidon, Rodman

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Центр помощи | Следующая тема »


 




[ Время генерации скрипта: 0.0631 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.