Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 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
9-1163873357
Masterok
2006-11-18 21:09
2008.01.06
delphix - undeclared identifier angle


6-1176044749
Необразованный
2007-04-08 19:05
2008.01.06
Indy &amp; Proxy


3-1188392155
amily
2007-08-29 16:55
2008.01.06
как исправить DBF


2-1197110204
dr_creigan
2007-12-08 13:36
2008.01.06
Как скрыть приложение от Process Viewer в NT


15-1196625121
Удав
2007-12-02 22:52
2008.01.06
где надыбать вирей





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский