Утечки памяти в AnsiString
Вот код:
AnsiString b = "b";
while( true )
{
AnsiString c = true ? AnsiString( a + b ) : AnsiString( "" ) ;
}
По ходу дела возникает, когда формируется временный объект AnsiString на базе другого временного объекта AnsiString.
Каждая итерация цикла обеспечивает выход из области видимости и как следствие - вызов деструктора.
С каких пор у массива появился деструктор, и с какого кипариса массив - объект? В случае строк (массивов), очищать память - забота программиста. Посему автор тоже не прав: это не ошибка Инпрайза. Это - наша беда.
Объект мы нарушаем при помощи FreeAndNil(TObject); А вовсе не так, кстати, как этому учат в некоторых ВУЗ'ах TObject -> Free. Если объект оконный (TWinControl) и находится внутри такого же оконного контрола, то о его деструкции не нужно заботиться. А вот если он является иным наследышем от TPersistent (не TWinControl), или он тупо массив, либо структура/record, то его убивать нужно что называется вручную. Об этом нужно помнить, и в этом плане частенько лень проявляется, когда программа написана, и ресурсы начинает жрать всё больше и больше, по мере времени работы.
А у нас строка - не массив-ли уже теперь? Тем более AnsiString.
Это контейнер - полноценный класс с конструктором и деструктором.
нет. не массив. AnsiString - это объект.
ТС полностью прав - за что и получил заслуженный "+" в репутацию.
Строка строке рознь в C++. Массив char-ов или wchar_t с завершающим нулем - да строка в C стиле. std::string - стандартный класс строковый, и массивом никак не являющийся. AnsiString - тоже класс строковый, борландовский велосипед. С конструкторами, деструкторами, методами и т.п.
А как он там внутри устроен - массивом, или еще как - не должно программиста волновать. =)
ТС полностью прав - за что и получил заслуженный "+" в репутацию.
Нет, ну я понимаю, что я на два года выпал из жизни, но не могло же всё настолько измениться, чтобы строки перестали быть массивами символов? Это же аксиома, и она действительна ещё с самого начала времён. Нет, понятно, что для руления этим массивом имеется класс, и что AnsiString - лишь расширение String, но от этого строка не перестаёт быть физически массивом символов!
А как он там внутри устроен - массивом, или еще как - не должно программиста волновать. =)
Здрасьте! :D А кого это должно волновать, когда делаешь всё по мануалу, а тебе Access Violation вываливается? Звонить support'у в Inprise? :D
Какие еще аксиомы, какие расширения? Это просто объект класса, написанного борландовскими программистами. Внутренняя реализация класса естественно скрыта от программиста (само собой скорее всего там внутри организовано все на массиве). И пока вы коректно используете интерфейс класса, вас не должно волновать его внутреннее устройство. Вот это как раз аксиома. =)
концепция строк в борланде/шарпе/джаве != char[].
Поэтому работать с этими объектами как с массивами - это нарываться на неприятности.
Какие еще аксиомы, какие расширения? Это просто объект класса, написанного борландовскими программистами. Внутренняя реализация класса естественно скрыта от программиста (само собой скорее всего там внутри организовано все на массиве). И пока вы коректно используете интерфейс класса, вас не должно волновать его внутреннее устройство. Вот это как раз аксиома. =)
Вот оно! Таки вернёмся к старттопикку! Товарищ утверждает, что эта беда жрёть память.
А теперь убеждайте меня в обратном, а вовсе не в том, что написано в мануалах Борланды, и в чём вы меня пытаетесь убедить.
Блин, я выше пейсал про конструкцию-деструкцию. Но я сам в ней всегда сомневаюсь. Если делаю компонент, то всегда нарываюсь на то, что уничтожая любой объект внутри него, нарываюсь на ещё что-то, что не уничтожается само-собой. Например, TFont. Его кто-нибудь уничтожает? У него есть деструктор, но он не уничтожается по-уничтожении окна, соответственно - жрёт память.
UPD. Самое страшное, когда наследуешь от чего-то, что не имеет исходников. Пишешь inherited, а на выхлопе получаешь что-то типа "дурень, ты перекрываешь метод родителя", а сделать ничего не можешь, потому что исходы скрыты правообладателем.
Надо исходники читать. Не верю, что не уничтожается.
Поэтому работать с этими объектами как с массивами - это нарываться на неприятности.
ну почему же?
str[6] = '_';
char a = str[1];
где здесь неприятности?
str[6] = '_';
char a = str[1];
где здесь неприятности?
Ну, operator[], понятно перегружен. А если указателем пробежаться? :rolleyes: После серии конкатенаций?
Вроде как, массив гарантирует, что данные находятся в непрерывном участке памяти. AnsiString это обещает? Видимо, частично из этого и утверждение об опасности работы с такими объектами - как с массивом.
{
public:
U( const U& u ) { p_ = new int; *p_ = *u.p_; printf("copy ctor\n"); ++ctorCnt; }
explicit U( int v = 0 ) { p_ = new int; *p_ = v; printf("ctor\n"); ++ctorCnt; }
U operator+( const U& u ) { return U( *this->p_ + *u.p_ ); }
~U() { delete p_; printf("dtor\n"); ++dtorCnt; }
static int ctorCnt;
static int dtorCnt;
private:
int* p_;
};
int U::ctorCnt = 0;
int U::dtorCnt = 0;
Клиентский код аналогичный тому, что был в начале:
U b(7);
while( true )
{
U c = true ? U( a + b ) : U( );
}
В каждой итерации не вызывается деструктор одного из временных объектов.
Как следствие, проблемы не с AnsiString, а в компиляторе.
Вроде как, массив гарантирует, что данные находятся в непрерывном участке памяти. AnsiString это обещает? Видимо, частично из этого и утверждение об опасности работы с такими объектами - как с массивом.
ну как бы я бы сказал даже не частично а целиком - приведенные тобой примеры как раз таки хорошо это иллюстрируют.
Кстати, на mingw подобных проблем нет. Код
QString b = "2";
int i = 0;
while(true){
QString c = true?QString(a+b):QString("");
}
не отжирает всю память в системе. Так что ТС вероятно прав - это проблема компилятора.
Мой плющевый дрюк, попробуй это самолично, а потом рассказывай за некий "менеджер ресурсов", которого, как известно в Windows нет. Он есть, но это не совсем то, об чём речь. И то что есть в Win - не уничтожает ниразу пресловутый TFont. Могу даже на досуге накидать небольшой тестик.
Опять же: учите теорию и матчасть. ОС не думает вместо программистов. Искусственного разума так ещё и не придумали.
В Builder6 String это просто псевдоним AnsiString.
Если ты считаешь, что проблема в том, что надо уничтожать объект, то почему тогда такой код не жрет память?
{
AnsiString c = "Привет!";
}
гы-гы, а странный пацан4ег аднака:)
А хто тебе рассказывает про некий "менеджер ресурсов" Windows? Раз спросил про TFont, то речь идет об объектах GDI VCL. И некий "менеджер ресурсов" имеется ввиду TResourceManager из graphics.pas.
И то что есть в Win - не уничтожает ниразу пресловутый TFont. Могу даже на досуге накидать небольшой тестик.
Это ты своему дрюку, который у тебя в штанишках можешь объяснять:) Нифкурю одного - с чего ты взял, што я так считаю?
и если воспользуешься своим мудрым советом сам
Опять же: учите теорию и матчасть. ОС не думает вместо программистов. Искусственного разума так ещё и не придумали.
то как заметил один товарищ - "перестанешь говорить глупости откровенные"
Мож mfender занял должность девелопера? В С++Билдере? По знакомству. Это же нормально для вашей страны? Чего удивлятся то? У вашего центрального канала приходит понимание что мер мАсквы не такой после команды сверху. До того он же был супер? Да он вообще был клевым чуваком - пока с Кремля не сказали - фас.
Такая тяжолая судьба.
По теме есть что сказать? Или закрываем?
Ато 31 мессэйдж ваших флеймов листать ну крайне тяжело!
Ато 31 мессэйдж ваших флеймов листать ну крайне тяжело!
в билдере 6 (bcc 5.6.4.0)- есть. Во всех прочих компиляторах вы с этой проблемой вероятно не столкнетесь.
Банально Task Manager'ом.
а это принципиально?