Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2004.09.05;
Скачать: [xml.tar.bz2];

Вниз

Как указатель превратить в строку?   Найти похожие ветки 

 
Aleksandr.   (2004-08-18 20:47) [0]

Есть базовый класс, у которого имеется массив TObject и методы для работы с ним.
Есть класс-потомок, у которого этот же массив помещаются строки (некоторая аналогия с TList/TStringList). Вот когда я по наивности попытался работать с ними по принципу
Inherited Put(Index,Pointer(Value)); //value - строка
и
result:=String(Inherited Get(Index))
такая пестня у меня проходит только один раз, то есть только при первой вставке и первом получении, а потом начинается Access Violation. Как корректно наколоть базовые методы работы с TObject, подсовывая им строку? или только через внутренний класс типа TStringObject?


 
Гаврила ©   (2004-08-18 21:30) [1]

Потому что компилятор сам считает ссылки на строку. При передаче как указатель подсчет ссылок невозможен? и происходит освободлене памяти. А в списке указатели на освобожденную память.
Вывод - использовать PChar. Выделение \ освободление памяти делать руками.
А Вообще спроектировано неправильно, как так - в предке - объекты, в потомке - строки


 
Юрий Зотов ©   (2004-08-18 21:37) [2]

Длинные строки относятся к данным с управляемым временем жизни. Это указатель, и указывает он на структуру в динамической памяти, которая хранит счетчик ссылок на строку и ее длину в байтах, после которых начинается уже само тело строки. Компилятор вставляет код, который автоматически меняет счетчик ссылок на строку и, если он стал равным нулю, строка уничтожается.

Поэтому вот такой код
S1 := S2
не создает новой строки. Два указателя получают одно и то же значение и увеличивается счетчик ссылок. Но если теперь написать
S1: = "Вася"  
то будет создана новая строка (со счетчиком, равным 1), а счетчик строки S2 декрементируется.

Когда точка выполнения кода выходит из области видимости переменной типа string (например, из процедуры, шде эта строка была объявлена локально), то счетчик ссылок на нее тоже декрементируется и если он стал равным нулю, строка уничтожается.

Теперь о том, что (предположительно) происходит у Вас. Когда Вы пишете Put(Index, Pointer(Value)) (где Value - строка), то Вы как бы обманываете компилятор. Он не настолько умен, чтобы понять, что здесь нужно увеличить счетчик ссылок на строку. Поэтому при выходе из метода счетчик декрементируется, становится равным нулю и строка Value уничтожается. В итоге получается, что запомненная Вами ссылка указывает уже в никуда - естественно, при попытке обращения к ней возникает AV.

Выходов несколько:
- управлять счетчиком ссылок вручную (очень не советую, это большой риск);
- создавать копию строки - см. StrNew, StrAlloc и StrDispose (тоже не советую - нужно будет очень аккуратно следить за ее своевременным уничтожением, при невнимательности есть риск получить утечку памяти);
- использовать нормальный TStringList (вот это советую - будет просто и надежно).


 
Aleksandr.   (2004-08-19 14:08) [3]

Спасибо. К сожалению, нормальный TStringList использовать невозможно - модуль должен иметь совместимость с Д7 и Д8 (зачем бы мне истчо было создавать аналоги коллекций и листов), а для .Net TStringList из Д7 как страшное ругательство. Операции с памятью отпадают по той же причине.
Мда, пришлось строить через объект TString, по Defines являющийся либо синонимом String .Net либо потомком TObject...


 
имя   (2004-08-19 17:10) [4]

Удалено модератором


 
Digitman ©   (2004-08-19 17:14) [5]

> [4]
редкий дебил под вечер долетит до середины Мастаков..



Страницы: 1 вся ветка

Форум: "Основная";
Текущий архив: 2004.09.05;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.46 MB
Время: 0.038 c
6-1087730110
amoral
2004-06-20 15:15
2004.09.05
У кого есть примеры/доки по написаню Proxy,Firewall, и про NDIS


1-1093229977
Vilux
2004-08-23 06:59
2004.09.05
TTree и прокрутка


3-1092135216
serga
2004-08-10 14:53
2004.09.05
interbase +KeyList.Strings


6-1088851846
BBoost
2004-07-03 14:50
2004.09.05
internet


3-1091967151
Piero
2004-08-08 16:12
2004.09.05
Dataset not in edit mode





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский