Экспертная система Delphi.int.ru

Сообщество программистов
Общение, помощь, обмен опытом

Логин:
Пароль:
Регистрация | Забыли пароль?

Delphi.int.ru Expert

Другие разделы портала

Переход к вопросу:

#   

Статистика за сегодня:  


Лучшие эксперты

Подробнее »



Вопрос # 4 218

/ вопрос открыт /

Приветствую, уважаемые эксперты!

используется TurboDelphi, создан класс:

type
TVarRes = record
Style : Integer;
NameVar : String;
end;

TListEdit = class(TCustomControl)
private
Vars : TStringList;
public
function GetParam(idx: integer): TVarRes;
....
end;

function TListEdit.GetParam(idx: integer): TVarRes;
var
p : TPanelEdit;
begin
p := TPanelEdit(Vars.Objects[idx]);
Result.Style := p.Style;

------------------------------------------------
ошибка исполнения в этой строке
Result.NameVar := Vars.Strings[idx];
------------------------------------------------
end;

исключение возникает в _LStrAsg (System.pas) - где указан комментарий об использовании глобальных и локальных переменных.

Голова отказывается понимать в чем проблема... на всякий случай пробовал переименовать переменные и создать в функции дополнительную переменную TVarRes - не помогло.

в чем может быть проблема появления исключения?

так-же замечу что класс разрабатывался 2 месяца назад и на этапе разработки класс успешно работал.

Тарасов Андрей Вопрос ожидает решения (принимаются ответы, доступен мини-форум)

Вопрос задал: Тарасов Андрей (статус: Посетитель)
Вопрос отправлен: 24 мая 2010, 11:03
Состояние вопроса: открыт, ответов: 0.


Мини-форум вопроса

Всего сообщений: 10; последнее сообщение — 24 мая 2010, 13:32; участников в обсуждении: 2.
Вадим К

Вадим К (статус: Академик), 24 мая 2010, 11:42 [#1]:

Кажется Вы выложили не совсем полные исходники. Вот пишете

Цитата (Тарасов Андрей):

ошибка исполнения в этой строке
Result.NameVar := Vars.Strings[idx];

А где же код, который вызывает эту строку?
Хотя кажется я знаю, где ошибка,но нужно увидеть больше сорцов.
Галочка "подтверждения прочтения" - вселенское зло.
Тарасов Андрей

Тарасов Андрей (статус: Посетитель), 24 мая 2010, 11:57 [#2]:

не понял зачем, но вот вызов

var
st: TVarRes;
begin
{тут собственно в цикле вызов,
ошибка при первом вызове - например так}
st := ListEdit.GetParam(0);

внутри класса функция не вызывается
Вадим К

Вадим К (статус: Академик), 24 мая 2010, 12:00 [#3]:

А покажите код, который складывает все это в TListEdit.
Код нужно показывать - тут не телепаты, они иногда конечно угадывают, но не всегда.
Галочка "подтверждения прочтения" - вселенское зло.
Тарасов Андрей

Тарасов Андрей (статус: Посетитель), 24 мая 2010, 12:13 [#4]:

че-то я вообще ничего не понимаю :(
какой-то дибильный глюк, вот более полный вызов:

var
idx,rc : integer;
st: TVarRes;
begin

// fGetParamSQL - форма на которой находится ListEdit

if fGetParamSQL.ShowModal = mrOk then
begin
rc := fGetParamSQL.ListEdit.CountVar;
for idx:=0 to rc do
begin

//добавил принудительный вызов 2-го элемента!!!
// это косяк - т.к. на ListEdit может быть всего 1 элемент
st := ListEdit.GetParam(1);

//и ошибка тут пропала
st := ListEdit.GetParam(idx);


то-ли со стеком какие-то непонятки, то-ли с компиляцией, бред какой-то

:(
Тарасов Андрей

Тарасов Андрей (статус: Посетитель), 24 мая 2010, 12:23 [#5]:

ну если интересна предистория - то вот (с детализацией)
------------------------------------------------
это происходит раньше

ListParam : TStringList;
ListParam.Add('Начальная дата=D_START=Дата');
ListParam.Add('Конечная дата=D_END=Дата');
DataSet.FieldByName('PAR_SQL').AsString := ListParam.Text;

-------------------------------------------------
так происходит присвоение

ListEdit.SetLines( DataSet.FieldByName('PAR_SQL').AsString );

-------------------------------------------------
реализация

// в классе рядом с Vars есть
List : TStringList;

procedure TListEdit.SetLines(data: String);
var
i : integer;
p : TPanelEdit;
s : TStringList;
begin
s := TStringList.Create();

List.Text := data;

for I := 0 to List.Count - 1 do
begin
p := TPanelEdit.Create(self);
p.Parent := self;
p.SetLabel(List.Names[i]);
List.Objects[i] := p;
s.Add(List.Values[List.Names[i]]);
end;

for I := 0 to List.Count - 1 do
begin
p := TPanelEdit(List.Objects[i]);
p.SetData(s.Values[s.Names[i]]);
Vars.AddObject( s.Names[i], p );
end;
s.Free;

CountVar := List.Count;

end;
Вадим К

Вадим К (статус: Академик), 24 мая 2010, 12:27 [#6]:

первая ошибка скорее всего тут
for idx:=0 to rc do
должно быть
for idx:=0 to rc-1 do
Галочка "подтверждения прочтения" - вселенское зло.
Тарасов Андрей

Тарасов Андрей (статус: Посетитель), 24 мая 2010, 12:41 [#7]:

да конечно - неудачно поправил после копипаста....

но я так понимаю что-то связано 0(нулевым) элементом массива

и этот косяк как-то связан с линковкой, предварительный вызов следующего элемента привел к "нормальной" работе компонента...

:(
Вадим К

Вадим К (статус: Академик), 24 мая 2010, 12:49 [#8]:

тут не линковка виновата, и не компилятор. Если происходит обращание к несуществующему элементу, то что же поделать.
Рекомендую в функции function GetParam(idx: integer): TVarRes;
вставить доп проверку на индекс.

Так код заработал после этого исправления?
Галочка "подтверждения прочтения" - вселенское зло.
Тарасов Андрей

Тарасов Андрей (статус: Посетитель), 24 мая 2010, 13:14 [#9]:

в функции, где возникает исключение пишут следующее:

_LStrAsg

This function is used when assigning to global variables.

Literals are copied to prevent a situation where a dynamically
allocated DLL or package assigns a literal to a variable and then
is unloaded -- thereby causing the string memory (in the code
segment of the DLL) to be removed -- and therefore leaving the
global variable pointing to invalid memory.

шайтан какой-то, а сейчас код заработал после принудительного вызова ПЕРВОГО элемента в списке

вот так пока оставил

st := ListEdit.GetParam(0);
st := ListEdit.GetParam(idx);

и конечный результат выдается правильно...

будет время - попробую сам разобраться
Вадим К

Вадим К (статус: Академик), 24 мая 2010, 13:32 [#10]:

Если говорить простым языком, то эта функция "компиляторная"
То есть, когда пишем
s := "str",
компилятор вставляет вызов этой функции.

Но представьте себе, что ей был передан несуществующий адрес или нулевой. И конечно будет ошибка. И ошибка не в ней, а где то в другом месте.
Итого, нужно искать, где был доступ к несуществующей памяти.
Галочка "подтверждения прочтения" - вселенское зло.

Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте.

Версия движка: 2.6+ (26.01.2011)
Текущее время: 22 февраля 2025, 11:31
Выполнено за 0.04 сек.