Форум: "Основная";
Текущий архив: 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