Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2003.06.12;
Скачать: CL | DM;

Вниз

Подскажите, выделяет ли память функция SetLength ..   Найти похожие ветки 

 
Alexsus   (2003-06-02 17:34) [0]

Подскажите, выделяет ли память функция SetLength для массивов структур или для этого нужно пользоваться GetMem

Зарание спасибо.


 
Skier ©   (2003-06-02 17:35) [1]

>Alexsus (02.06.03 17:34)
Код свой покажи, всё и выяснится...


 
Alexsus   (2003-06-02 17:48) [2]

Сами структуры

TCCondition = record
OprId : String;
Oper1 : String;
Oper2 : String;
end;
TCField = record
TblId : String;
TblPK : String;
CndNum : Integer;
CndArray : array of TCCondition;
end;

Добавляю элемент
Var fld : TCField;
begin
inc(fld.CndNum);
SetLength(fld.CndArray,fld.CndNum);
end;

после двух трёх итераций программа сваливается ((


 
Skier ©   (2003-06-02 17:51) [3]

Судя по всему ты добавляешь в массив, т.е. размер массива
меняется.
Если так, то лучше использовать для этой цели TList или его
потомок...


 
Alexsus   (2003-06-02 17:56) [4]

Не хочу показаться назойливым )), можно небольшой примерчик ?
И неужели нельзя обойтись без использования каких то стандартных классов ? Просто в том же VB есть необходимые средства, а Delphi должно быть вроде как помощнее.


 
Юрий Зотов ©   (2003-06-02 17:57) [5]

Попробуйте так:

PCCondition = ^TCCondition; //!!
TCCondition = record
OprId: String;
Oper1: String;
Oper2: String;
end;

TCField = record
TblId : String;
TblPK : String;
CndNum : Integer;
CndArray: array of PCCondition; //!!
end;

После этого, думаю, SetLength должна работать нормально. Но вот память под сами записи придется выделять/освобождать ручками:
New(CndArray[i]);
Dispose(CndArray[i]);


 
Sandman25 ©   (2003-06-02 17:59) [6]

Alexsus (02.06.03 17:56)
Я только что прогнал Вашу программу у себя. Все работает нормально, даже после 10 "итераций". Покажите весь Ваш код, относящийся к работе с данными записями.


 
Alexsus   (2003-06-02 18:00) [7]

Спасибо буду пробовать.


 
Sandman25 ©   (2003-06-02 18:01) [8]

Юрий Зотов © (02.06.03 17:57)

То есть если понадобится массив of integer, то придется использовать pinteger? Я думаю, надо разобраться, почему у человека программа вылетает.


 
Skier ©   (2003-06-02 18:04) [9]

>Alexsus
При работе с дин. массивами нужно помнить :
-что дин. массивы это структуры с контролируемым
временем жизни (как и строки).
-при присваивании массива происходит не копирование значений, а
копирование адреса массива


 
Alexsus   (2003-06-02 18:07) [10]

// Тип описания элемента дерева кубов
PCubeElement = ^TCubeElement;
TCubeElement = record
ElType : String;
ElID : String;
ElName : String;
TblId : String; // ID таблицы
TblPK : String; // Первичный ключ таблицы
end;
// Типы описания запроса
TCCondition = record // --- Условия
CndCode : Integer; // Код условия
OprId : String; // ID операции
Oper1 : String; // Операнд 1
Oper2 : String; // Операнд 2
end;
TCField = record
FldID : String; // ID поля
FldName : String; // Название поля
Belong : String; // Принадлежность(изм/перем)
SlcFlag : Boolean; // Флаг выборки
TblId : String; // ID таблицы
TblPK : String; // Первичный ключ таблицы
CndNum : Integer; // Количество условий
CndArray : array of TCCondition; // Условия
end;
TCQuery = record // --- Запрос
CubId : String; // ID куба
CubName : String; // Название куба
QryID : String; // ID запроса
QryName : String; // Название запроса
FldNum : Integer;// Количество полей
FldArray : array of TCField;
end;

Var
CTree : array of TCubeElement; // Объявлена в отдельнов модуле
Query : TCQuery; объявлена public секции формы
begin
inc(Query.FldNum);
SetLength(Query.FldArray,Query.FldNum);
Query.FldArray[Query.FldNum-1].FldID := PCubeElement(Selected.Data)^.ElID;
Query.FldArray[Query.FldNum-1].FldName := PCubeElement(Selected.Data)^.ElName;

myLst.Caption := Query.FldArray[Query.FldNum-1].FldID + " - " +Query.FldArray[Query.FldNum-1].FldName;
myLst.Data := PString(@Query.FldArray[Query.FldNum-1].FldID)

// Сваливается после при обращении полям data добавленных элементов
end;


 
Skier ©   (2003-06-02 18:17) [11]

Вот это весьма опасно, стоит подумать...
PString(@Query.FldArray[Query.FldNum-1].FldID)


 
Alexsus   (2003-06-02 18:19) [12]

А какие альтернативы ??


 
Skier ©   (2003-06-02 18:21) [13]

>Alexsus (02.06.03 18:19)
-> Pointer(Query.FldArray[Query.FldNum-1].FldID)
<- Integer(myLst.Data)



 
Serginio   (2003-06-02 18:22) [14]

Вообщето нужно обнулять стековые переменные перед использованием
Var fld : TCField;
begin
FillChar(fld,SizeOf(TCField),0);
inc(fld.CndNum);
SetLength(fld.CndArray,fld.CndNum);
end;
Во всяком случае у меня таких проблем не было.



 
Sandman25 ©   (2003-06-02 18:22) [15]

>myLst.Data := PString(@Query.FldArray[Query.FldNum-1].FldID)

Каково описание myLst?

По-моему, нужно выделить память под myLst.Data и скопировать строку, а не просто присвоить указатель на нее.


 
Alexsus   (2003-06-02 18:25) [16]

var
myLst : TListItem;

begin
myLst := lsvAttr.Items.Add;
myLst.Caption := Query.FldArray[Query.FldNum-1].FldID;
myLst.Data := PString(@Query.FldArray[Query.FldNum-1].FldID)
end;


 
Sandman25 ©   (2003-06-02 18:27) [17]

Возможно, поможет
@Query.FldArray[Query.FldNum-1].FldID[1]

Как происходит дальнейшее использование data?



 
Alexsus   (2003-06-02 18:31) [18]

Немного не понял FldID переменная типа string, что будет означать обращение FldID[1] ?? Data используется для ссылки на элементы выше описанных структур.



 
Skier ©   (2003-06-02 18:31) [19]

А какой тип у FldID ?
если строковый, то мой пост (02.06.03 18:21) отменяется !


 
Sandman25 ©   (2003-06-02 18:33) [20]

Адрес первого символа.

Если потом происходит присваивание
var p: pchar;
begin
p := pchar(mylst.data);

На какой именно строке просходит вылет программы? Я поэтому спрашиваю, как именно используется data.


 
Skier ©   (2003-06-02 18:33) [21]

var
AStr : PString;
begin
//...........
New(AStr);
AStr^ := Query.FldArray[Query.FldNum-1].FldID;
myLst.Data := AStr
//...........
end;

Использование : PString(myLst.Data)^



 
Serginio   (2003-06-02 18:37) [22]

2(Skier) То что валится динамический массив это совсем не значит, что TList лучше динамического массива. Очень давно работаю с динамическими массивами и не разу не было что бы они валились а структуры были очень сложные.


 
Skier ©   (2003-06-02 18:39) [23]

>Serginio (02.06.03 18:37)
Рад за тебя !


 
Alexsus   (2003-06-02 18:41) [24]

VAr
lsvAttr: TListView;

for i:=0 to lsvAttr.Items.Count-1 do
begin
if PString(lsvAttr.Items[i].Data)^ = PCubeElement(Selected.Data)^.ElID
then
...
end;
Вылет происходит при обращении к PString(lsvAttr.Items[i].Data)^ для тех элементов которые добавлялись SetLength по одному,а не при начальном создании всего массива, и то не сразу а только после добавления 1,2 элементов


 
Serginio   (2003-06-02 18:42) [25]

2(Skier) Большое спасибо за Вашу радость.
2 (Alexsus) Не мог бы поподробнее показать код с динамическими массивами и какие значения наблюдал в отладчике. А именно
fld.CndNum; и
Length(fld.CndArray);



 
Sandman25 ©   (2003-06-02 18:49) [26]

Alexsus
см. Skier © (02.06.03 18:33)
Если делать по его методике, то проблем быть не должно.
У Вас освобождалась память, выделенная под строки (так как ссылок на нее уже не было), и при следующем выделении памяти в то же место записывались другие данные.



 
VMcL ©   (2003-06-02 18:50) [27]

>Alexsus (02.06.03 17:34)
Initialize, Finalize.


 
Alexsus   (2003-06-02 18:56) [28]

fld.cndarray заполняется далее и в данном месте роли играть по моему не должен, ошибка возникает при добавление элементов Query.FldArray причем значения Query.CndNum и Length(Query.FldArray) увеличивается


 
Serginio   (2003-06-02 18:57) [29]

Используй метод Skier © (02.06.03 18:33) так как ссылки на строки весьма опасны.


 
Serginio   (2003-06-02 19:00) [30]

Теперь осталось спросить и строки присваиваются. И что такое Selected.Data


 
Alexsus   (2003-06-02 19:07) [31]

Строки присваиваются. TTreeView(t).Selected.Data


 
Serginio   (2003-06-02 19:20) [32]

Теперь осталось спросить откуда ссылки на TTreeView(t).Selected.Data. Да уж намешано у тебя будь здоров. Не думаю, что проблема с динамическими массивами


 
Alexsus   (2003-06-02 19:24) [33]

t : TreeView это просто компонент на форме, при работе с ним вряд ли могли возникнуть ошибки. Ошибки возникают только когда я по одному начинаю создавать новые элементы структур. При выделении памяти заранее этого не происходит.


 
Serginio   (2003-06-02 19:31) [34]

Откуда в TTreeView(t).Selected.Data появляются данные??? из твоего кода только можно гадать.
2. Цел ли еще массив так как у тебя строки ссылаются на элементы массива.
3. Пробовал ли Используй метод Skier © (02.06.03 18:33) так как ссылки на строки весьма опасны.



 
Alexsus   (2003-06-02 19:39) [35]

Имеется в виду пост Skier © (02.06.03 18:33) ??
В данный момент пробую но особых продвижений нет((


 
Serginio   (2003-06-02 19:43) [36]

А есть возможность того, что Selected.Data вообще не существует???


 
Song ©   (2003-06-02 19:50) [37]

А есть возможность того, что Selected.Data вообще не существует???

Запросто.
TTreeNode.Data:=nil;


 
Serginio   (2003-06-02 19:58) [38]

2(Song) Это вопрос Alexsus так как у него присваивается
Query.FldArray[Query.FldNum-1].FldID := PCubeElement(Selected.Data)^.ElID;


 
Alexsus   (2003-06-02 20:03) [39]

Нет такой возможности TTreeNode.Data везде существует.


 
Alexsus   (2003-06-02 20:24) [40]

Всем огромное спасибо ! В первом приближении заработало.



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

Текущий архив: 2003.06.12;
Скачать: CL | DM;

Наверх




Память: 0.56 MB
Время: 0.04 c
1-34877
romeomd
2003-05-31 13:41
2003.06.12
TreeView


8-34941
~Mr.L@g~
2003-02-26 15:13
2003.06.12
Дисплей компонента TMediaPlayer


3-34718
Крот
2003-05-23 12:51
2003.06.12
Перемещение курсора


1-34853
Апатин Даниил
2003-05-29 22:47
2003.06.12
Оформление Edit a


14-35012
vidiv
2003-05-27 01:20
2003.06.12
Кто придумал smtp? и как настроить MDaemon, чтобы ...(не влезает)