Форум: "Начинающим";
Текущий архив: 2008.01.06;
Скачать: [xml.tar.bz2];
Внизраспределение памяти в динмаическом массиве записей Найти похожие ветки
← →
Nil (2007-12-06 14:47) [0]С виду тревиальная задача: нужен динамический массив элементами которго являются записи. Вот что я налабал:
const
MAXDRVCOUNT=1000;
type
pDrvRec = ^TDrvRec;
TDrvRec=record
ClassName,
ClassGUID,
DevName,
HardwareID,
CompatibleIDS,
DeviceClassName,
Manufacturer,
FriendlyName,
DriverDate,
ProviderName,
DriverVersion,
DriverDesc: string[255];
ClassIm: integer;
end;
PDrvArr = ^TDrvArr;
TDrvArr = array [1..MAXDRVCOUNT] of pDrvRec;
public
{ Public declarations }
DrvList: pDrvArr;
.................
for I := 1 to 100 do
begin
ReAllocMem(MainForm.DrvList,i*sizeof(TDrvRec)+4);
MainForm.DrvList[i]^.ClassName:= "Hello"; - вот здесь AcessViolation
end;
не понятно почему ошибка возникает на 3-м шаге цикла. подскажите пож где грабли?
заранее благодарен
← →
Dib@zol © (2007-12-06 14:50) [1]А не легше ли так:
DrvList:array of TDrvRec + SetLength + Finalize
???
← →
Юрий Зотов © (2007-12-06 15:00) [2]> Nil (06.12.07 14:47)
Да... понакручено. Указатель на массив указателей....
Зачем усложнять жизнь самому себе? Если нужен динамический масив, так динамический массив и используйте, без всякого мудрежа.
← →
Nil (2007-12-06 15:19) [3]> Dib@zol
увидел скелет в каком то примере ну и развил его до своей задачи
а под Finalize что подразумевается?
← →
Германн © (2007-12-06 15:20) [4]Ну разве что для ТП.
← →
Сергей М. © (2007-12-06 15:32) [5]
> нужен динамический массив
> Вот что я налабал
В "налабанном" динамическим массивом и не пахнет.
← →
Германн © (2007-12-06 15:41) [6]
> В "налабанном" динамическим массивом и не пахнет.
В "налабанном" пахнет граблями, что автор и сам признал. А не надо бездумно тащить из тырнета всё то барахло, которое там валяется с незапамятных времен.
← →
Nil (2007-12-06 15:43) [7]> Сергей М.
спасибо что заметили!!
обратите внимание на тему "нужен динамический массив" а не "есть динамический массив"
а по существу вопроса можете что нибудь предложить, кроме того что вы увидели [1..MAXDRVCOUNT]?
← →
Palladin © (2007-12-06 15:45) [8]
const
MAXDRVCOUNT=1000;
type
pDrvRec = ^TDrvRec;
TDrvRec=record
ClassName,
ClassGUID,
DevName,
HardwareID,
CompatibleIDS,
DeviceClassName,
Manufacturer,
FriendlyName,
DriverDate,
ProviderName,
DriverVersion,
DriverDesc: string[255];
ClassIm: integer;
end;
PDrvArr = ^TDrvArr;
TDrvArr = array [1..MAXDRVCOUNT] of pDrvRec; // размер элемента массива = SizeOf(pDrvRec)
public
{ Public declarations }
DrvList: pDrvArr;
.................
for I := 1 to 100 do
begin
ReAllocMem(MainForm.DrvList,i*sizeof(TDrvRec)+4); // почему делаем реаллок по размеру SizeOf(TDrvRec) да еще +4
MainForm.DrvList[i]^.ClassName:= "Hello"; - вот здесь AcessViolation // почему обращаемся к неинициализированному указателю?
end;
← →
Германн © (2007-12-06 15:46) [9]
> а по существу вопроса можете что нибудь предложить, кроме
> того что вы увидели [1..MAXDRVCOUNT]
Объясни сперва эту вот строчку
> ReAllocMem(MainForm.DrvList,i*sizeof(TDrvRec)+4);
тогда и по существу поговорим.
← →
Германн © (2007-12-06 15:46) [10]Тимур опередил :)
← →
Сергей М. © (2007-12-06 15:52) [11]
> Nil (06.12.07 15:43) [7]
По существу - если нужен динамический массив, следует объявить именно динамический массив. В чем проблема ?
← →
Юрий Зотов © (2007-12-06 19:25) [12]> Nil (06.12.07 14:47)
Динамический масив МОЖНО реализовать через указатели, но, взявшись за это, надо, как минимум, понимать, что такое указатели и как с ними работать (сколько и когда выделять памяти, как с нею обращаться, когда ее освобождать и т.п.). И если с этим есть проблемы, то гораздо проще использовать дельфишные динамические массивы:
type
TDrvRec = record
...
end;
var
DrvArr: array of TDrvRec;
Это все, что требуется. И никаких указателей. И имеем самый настоящий динамический массив. Как с ними работать - см. в справке топик "Dynamic Arrays".
← →
Nil (2007-12-06 19:50) [13]> Palladin
> почему делаем реаллок по размеру SizeOf(TDrvRec) да еще +4
+4 это уже пальцем в небо тыкал, не обращайте внимания, а SizeOf(TDrvRec) я так понимаю чтобы добавить новый элемент к массиву, нужно выделить столько сколько занимает моя запись. или ошибаюсь?
> Юрий Зотов
а при таком подходе SetLength использовать для добавления? ничего что там нестандартный тип данных, а мною придуманный? я раньше с такими массивами не сталкивался, когда то в теории было, не помню, так что прошу не бранится за возможно глупые высказывания по этому поводу
я так понимаю чтобы инициализировать ещё один элемент в массиве нужен
SetLength(MainForm.DrvList,1);
GetMem(MainForm.DrvList, sizeof(TDrvRec));
правильно понял? или GetMem в этом случае уже не нужен?
> Германн ©
sizeof(TDrvRec) я так понимаю 12*255+4=3064 байт
изначально под MainForm.DrvList выделено 0 байт
ReAllocMem(MainForm.DrvList,1*sizeof(TDrvRec));
теперь MainForm.DrvList 3064
ReAllocMem(MainForm.DrvList,2*sizeof(TDrvRec));
теперь MainForm.DrvList 3064*2 и это уже 2 элемента в массиве и т.д.
я правильно понимаю как это работает? если нет поправьте пож, хочется всё таки понять как с такими зверями обращаться в будущем
← →
Юрий Зотов © (2007-12-06 19:58) [14]> Nil (06.12.07 19:50) [13]
> а при таком подходе SetLength использовать для добавления?
Да. Точнее, для изменения длины при добавлении (или сокращении).
> ничего что там нестандартный тип данных, а мною придуманный?
Нормально, никакой разницы нет.
> чтобы инициализировать ещё один элемент в массиве нужен
SetLength(MainForm.DrvList, Length(MainForm.DrvList) + 1);
Этот код добавляет в конец массива еще один элемент. И никаких GetMem. Элемент уже готов и с ним можно работать.
← →
Германн © (2007-12-06 21:18) [15]
> > Германн ©
>
> sizeof(TDrvRec) я так понимаю 12*255+4=3064 байт
> изначально под MainForm.DrvList выделено 0 байт
>
> ReAllocMem(MainForm.DrvList,1*sizeof(TDrvRec));
> теперь MainForm.DrvList 3064
>
> ReAllocMem(MainForm.DrvList,2*sizeof(TDrvRec));
> теперь MainForm.DrvList 3064*2 и это уже 2 элемента в массиве
> и т.д.
>
> я правильно понимаю как это работает? если нет поправьте
> пож, хочется всё таки понять как с такими зверями обращаться
> в будущем
>
Нет неправильно. Потому что массив DrvList: pDrvArr; это массив указателей на структуры, а не массив самих структур. А вот под сами структуры ты как раз память не выделял. Оттуда и AV.
← →
Rouse_ © (2007-12-06 21:28) [16]Мошт это подойдет?
http://rouse.drkb.ru/tmp/devlist.zip
> увидел скелет в каком то примере ну и развил его до своей
> задачи
Это действительно скелет, и чтоб вдохнуть в него жизнь нужно память под все элементы выделить. Указатель на массив указателей - а что? Креатиф :)))
← →
Nil (2007-12-07 01:01) [17]> Юрий Зотов
вери мач как говорится!) завтра попробую
> Германн
т.е. если всё таки уперется рогами в мой случай то получается нужно сначала
ReAllocMem(MainForm.DrvList,1*sizeof(pDrvRec)); это инициализация нового элемента в массиве
а потом
ReAllocMem(MainForm.DrvList[1],1*sizeof(TDrvRec)); это инициализация содержимого этого элемента
правильно понял?
> Rouse_
спасибо этот пример уже видел, у меня немножко другая задача, автообновление драйверов на компе, хотя с этого примера много полезного почерпнул. больше понравились демки из jediapilib
кста, http://rouse.drkb.ru/ много интересной инфы. отдельное спасибо!
← →
Германн © (2007-12-07 01:22) [18]
> Nil (07.12.07 01:01) [17]
>
...
> > Германн
> т.е. если всё таки уперется рогами в мой случай то получается
> нужно сначала
> ReAllocMem(MainForm.DrvList,1*sizeof(pDrvRec)); это инициализация
> нового элемента в массиве
> а потом
> ReAllocMem(MainForm.DrvList[1],1*sizeof(TDrvRec)); это инициализация
> содержимого этого элемента
> правильно понял?
>
Не. Лучше описать массив TDrvArr какarray [1..MAXDRVCOUNT] of TDrvRec;
Тогда всё остальное будет верным. Ну и ещё плюс четверку выбросить надо :)
А описывать вышеуказанный массив какarray [1..MAXDRVCOUNT] of pDrvRec;
просто глупо.
Имхо, сей "надыбанный" пример был для ТурбоПаскаль или для младших версий Дельфи, когда ещё не было динамических массивов. Тогда это было единственным способом реализовать массив с заранее (на этапе компиляции) не известными размерами.
← →
Галинка © (2007-12-07 11:40) [19]осмелюсь предположить, что [1..MAXDRVCOUNT] не пригодится в принципе.
← →
Anatoly Podgoretsky © (2007-12-07 12:10) [20]Пригодится, только называеть его динамическим не стоит.
← →
Palladin © (2007-12-07 13:43) [21]
> Галинка © (07.12.07 11:40) [19]
очень даже пригодится на этапе компиляции в случае обращения к фиксированным индексам массива
← →
Галинка © (2007-12-07 15:01) [22]Вот и я о том же. Или не динамический, читай не массив переменной длины. Или зачем тогда максимальную длину сразу выделять?
Palladin © (07.12.07 13:43) [21]
конечно не зная задачи трудно сказать. Но чтобы обратится к пятому элементу, надо всего лишь сделать SetLength(<arr_name>, 5). И он уже будет. Так что по идее AV уже не должно вываливаться?
← →
Palladin © (2007-12-07 15:10) [23]
> Галинка © (07.12.07 15:01) [22]
это в случае динамических массивов, в случае
PMyArr=^TMyArr
TMyArr=Array [0..1] of чего то там
такое не сканает
← →
Alex (2007-12-07 15:12) [24]А не проще сделать так:
type
TMyRecord = ... end;
var
MyVar:array of TMyRecord;
begin
SetLength(MyVar, скока хочешь)
for i:=0 to Length(MyVar)-1 do
begin
делаешь с MyVar[i] че хочешь
end;
:))))))))))
end;
← →
Palladin © (2007-12-07 15:17) [25]
> Alex (07.12.07 15:12) [24]
проще, но у автора бзик сделать через содранный пример
← →
Галинка © (2007-12-07 15:24) [26]Palladin © (07.12.07 15:10) [23]
ну понятно. Там же массив фиксированных размеров. Поддерживаю рецепт Алекса.
← →
Palladin © (2007-12-07 15:26) [27]
> Галинка © (07.12.07 15:24) [26]
рецепт был выписан давно, еще в самом начале, больной не поддался лечению
← →
Nil (2007-12-07 20:11) [28]
> Имхо, сей "надыбанный" пример был для ТурбоПаскаль или для
> младших версий Дельфи, когда ещё не было динамических массивов.
> Тогда это было единственным способом реализовать массив
> с заранее (на этапе компиляции) не известными размерами.
>
вот теперь легче спать) я просто помню со времён паскаля я как то очень сильно извращался чтобы такое сделать, поэтому и зацепился за этот пример
> Alex
так и сделал
всем спасибо за разъяснения!
Страницы: 1 вся ветка
Форум: "Начинающим";
Текущий архив: 2008.01.06;
Скачать: [xml.tar.bz2];
Память: 0.53 MB
Время: 0.006 c