Создание своего класса
От: FewartPro  
Дата: 16.07.09 22:24
Оценка: :)
Здраствуйте!!!

Помогите решить проблему.

Осваиваю создание своих классов на C++ Borland, и у меня такая проблема: Есть файл MyStringList.h, в котором такой код:

class TMyStringList
{
private:
TList *lList;

int __fastcall GetCount();

AnsiString __fastcall GetValue(int iIndex);
void __fastcall SetValue(int iIndex, AnsiString iValue);
public:

TMyStringList();
__property AnsiString Value[int iIndex] = {read = GetValue, write = SetValue};
__property int Count = {read = GetCount};

void __fastcall Clear();
void __fastcall Add(AnsiString iValue);
void __fastcall Delete(int iIndex);

~TMyStringList();
};

TMyStringList::TMyStringList()
{
this->lList = new TList;
}

TMyStringList::~TMyStringList()
{
delete this->lList;
this->lList = NULL;
}

AnsiString __fastcall TMyStringList::GetValue(int iIndex)
{
return *(AnsiString*)this->lList->Items[iIndex];
}

void __fastcall TMyStringList::SetValue(int iIndex, AnsiString iValue)
{
*(AnsiString*)this->lList->Items[iIndex] = iValue;
}

int __fastcall TMyStringList::GetCount()
{
return this->lList->Count;
}

void __fastcall TMyStringList::Add(AnsiString iValue)
{
AnsiString *iVal = new AnsiString;
*iVal = iValue;
this->lList->Add(iVal);
}

void __fastcall TMyStringList::Clear()
{
int i;

for(i=this->lList->Count-1; i>-1; i--)
{
this->Delete(i);
}
this->lList->Clear();
}

void __fastcall TMyStringList::Delete(int iIndex)
{
AnsiString *iValue;
iValue = (AnsiString *)this->lList->Items[iIndex];
delete iValue;

this->lList->Delete(iIndex);

this->lList->Pack();
}

Затем в файле Unit1.cpp, есть код:

TMyStringList *StringList = new TMyStringList();
StringList->Add("123");
ShowMessage(StringList->Value[0]); \\Здесь выводит 123
delete StringList;
ShowMessage(StringList->Value[0]); \\Здесь за место ошибкиAccess violation at address), выдает значение "", после чего вылезает ошибка ...class EInvalidPointer with message "Invalid pointer operation"...
Подскажите какие ошибки я допускаю при создании класса?
Re: Создание своего класса
От: _Ursus_  
Дата: 17.07.09 02:34
Оценка:
Здравствуйте, FewartPro, Вы писали:

FP>TMyStringList *StringList = new TMyStringList();

FP>StringList->Add("123");
FP>ShowMessage(StringList->Value[0]); \\Здесь выводит 123
FP>delete StringList;
FP>ShowMessage(StringList->Value[0]); \\Здесь за место ошибки

В жирном месте объект убили, а строчкой ниже пытаются уже дохлый объект растормошить
Re[2]: Создание своего класса
От: BulatZiganshin  
Дата: 17.07.09 07:09
Оценка:
Здравствуйте, _Ursus_, Вы писали:

_U_>В жирном месте объект убили, а строчкой ниже пытаются уже дохлый объект растормошить


технологии вуду
Люди, я люблю вас! Будьте бдительны!!!
Re: Создание своего класса
От: Fwiffo Россия  
Дата: 17.07.09 09:38
Оценка:
Здравствуйте, FewartPro, Вы писали:

FP>Здраствуйте!!!


FP>delete StringList;

FP>ShowMessage(StringList->Value[0]); \\Здесь за место ошибкиAccess violation at address), выдает значение "", после чего вылезает ошибка ...class EInvalidPointer with message "Invalid pointer operation"...
FP>Подскажите какие ошибки я допускаю при создании класса?

Я не понял, вам формулировка сообщения об ошибке не нравится или что?
Re: Создание своего класса
От: denisko http://sdeniskos.blogspot.com/
Дата: 17.07.09 09:41
Оценка: :))
Здравствуйте, FewartPro, Вы писали:

FP>Здраствуйте!!!


FP>Помогите решить проблему.


FP>Осваиваю создание своих классов на C++ Borland


Не трогай дядю за носик и вообще отойди от гроба.


FP>Затем в файле Unit1.cpp, есть код:


FP>TMyStringList *StringList = new TMyStringList();

FP>StringList->Add("123");
FP>ShowMessage(StringList->Value[0]); \\Здесь выводит 123
FP>delete StringList;
FP>ShowMessage(StringList->Value[0]); \\Здесь за место ошибкиAccess violation at address), выдает значение "", после чего вылезает ошибка ...class EInvalidPointer with message "Invalid pointer operation"...
FP>Подскажите какие ошибки я допускаю при создании класса?
Ты сначала убил объект, а потом к нему обращаешься. Вот скажи: если бы с тобой так поступили (сначала убили, а потом спросили который час) тебе бы понравилось?
<Подпись удалена модератором>
Re[2]: Создание своего класса
От: byleas  
Дата: 17.07.09 10:37
Оценка:
Здравствуйте, denisko, Вы писали:

D>Не трогай дядю за носик и вообще отойди от гроба.

Этот дядя одним из первых (из коммерческих компиляторов) добавил частичную (и немалую) поддержку фич C++0x
Re[3]: Создание своего класса
От: denisko http://sdeniskos.blogspot.com/
Дата: 17.07.09 11:14
Оценка:
Здравствуйте, byleas, Вы писали:

B>Здравствуйте, denisko, Вы писали:


D>>Не трогай дядю за носик и вообще отойди от гроба.

B>Этот дядя одним из первых (из коммерческих компиляторов) добавил частичную (и немалую) поддержку фич C++0x
Этот дядя умеет добавлять поддержку кучи непереносимых вещей, с которыми потом приходиццо трахацца.
<Подпись удалена модератором>
Re[2]: Создание своего класса
От: FewartPro  
Дата: 24.07.09 19:33
Оценка:
Здравствуйте, Fwiffo, Вы писали:

F>Здравствуйте, FewartPro, Вы писали:


FP>>Здраствуйте!!!


FP>>delete StringList;

FP>>ShowMessage(StringList->Value[0]); \\Здесь за место ошибкиAccess violation at address), выдает значение "", после чего вылезает ошибка ...class EInvalidPointer with message "Invalid pointer operation"...
FP>>Подскажите какие ошибки я допускаю при создании класса?

F>Я не понял, вам формулировка сообщения об ошибке не нравится или что?


Проблема в том, что посмотрев работу встроенных классов в Borland C++, например такой код:

TStringList *slStringList = new TStringList();
slStringList->Add(123);
ShowMessage(slStringList->Strings[0]); //Здесь выводит значение: 123
delete slStringList;
ShowMessage(slStringList->Strings[0]); //Здесь выводит ошибку (..class EAccessViolation with message 'Access violation at address...), в отличии от созданного мной класса который выдает значение: "".
Поэтому меня и интересует может я что делаю не так при создании класса?. Не происходит ли утечки памяти в созданном мною классе?. Посоветуйте какие нибудь книги по созданию классов на C++ Borland.
Re[3]: Создание своего класса
От: Юрий Жмеренецкий ICQ 380412032
Дата: 25.07.09 03:21
Оценка: 3 (1)
Здравствуйте, FewartPro, Вы писали:
...
F>>Я не понял, вам формулировка сообщения об ошибке не нравится или что?

FP>Проблема в том, что посмотрев работу встроенных классов в Borland C++, например такой код:


FP>TStringList *slStringList = new TStringList();

FP>slStringList->Add(123);
FP>ShowMessage(slStringList->Strings[0]); //Здесь выводит значение: 123
FP>delete slStringList;
FP>ShowMessage(slStringList->Strings[0]); //Здесь выводит ошибку (..class EAccessViolation with message 'Access violation at address...), в отличии от созданного мной класса который выдает значение: "".

В С++ поведение программ, содержащих неопределенное поведение, никак не специфицированно. Результатом может быть и "", и "1", и access violation, и т.д. Такая программа даже не обязана компилироваться.

Неопределенное поведение возникает здесь:
TMyStringList *StringList = new TMyStringList();
//...
delete slStringList;
ShowMessage(slStringList->Strings[0]);


Выражение 'slStringList->Strings[0]' эквивалентно '(*slStringList).Strings[0]', которое содержит разыменование указателя. Но после выполнения 'delete' указатель имеет 'инвалидное' значение, доступ к которому приводит к неопределенному поведению.

FP>Поэтому меня и интересует может я что делаю не так при создании класса?.

Это совершенно другой вопрос.

FP>Не происходит ли утечки памяти в созданном мною классе?.


Вот в этом коде:
class TMyStringList
{
private:
TList *lList;

//...
};

TMyStringList::TMyStringList()
{
  this->lList = new TList;
}

TMyStringList::~TMyStringList()
{
  delete this->lList;
  this->lList = NULL;
}

void TMyStringList::Add(AnsiString iValue)
{
  AnsiString *iVal = new AnsiString;
  *iVal = iValue;
  this->lList->Add(iVal);
}
//...
TMyStringList *StringList = new TMyStringList();
StringList->Add("123");
ShowMessage(StringList->Value[0]); 
delete StringList;


наличие утечек зависит от того, что из себя представляет TList (точнее — выполняется ли в деструкторе TList удаление элементов, добавленных с помощью TList::Add). Есть подозрения (вызванные наличием функции TMyStringList::Clear) в том, что такого удаления в деструкторе не производится.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.