|  | 
 
 | 
| 
 | |||||||
| Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны | 
|  | 
|  | Опции темы | Поиск в этой теме | Опции просмотра | 
| 
			 
			#1  
			
			
			
			
		 | ||||||||||
| 
 | ||||||||||
|  Добавление записи в динамический массив Здравствуйте. Столкнулся с некоторыми проблемами при создании объекта и массива этого-же объекта, конкретно - с манипуляцией элементов в массиве. Объект содержит только энный набор данных и несколько функций "одиночной" обработки. Код: 
 Код: 
 Код: 
 2я проблема в добавлении элемента - для этого вызывается AddNew (ICommand: TCommand): Код: 
 Код: 
 Последний раз редактировалось Velz, 02.04.2012 в 16:19. | 
| 
			 
			#2  
			
			
			
			
		 | ||||||||||
| 
 | ||||||||||
|   Если собрались использовать array of TCommandStackElement, то надо так PCommandStackElmt = ^TCommandStackElmt; - выкинуть. Код: 
 вместо Код: 
 Код: 
 Убрать ^ при обращении к PCommandStack. и что Вы хотели сделать здесь Код: 
 Код: 
 Если Вы вот этим кодом @Command:=@ICommand; хотите побайтно скопировать содержимое объекта TCommand - то хочу разочаровать - ничего не выйдет. И немножко ликбеза. Экземпляры классов в дельфи - всегда указатели. Копирующего конструктора и поэлементного присваивания по умолчанию для классов НЕТ !. Если они нужны - нужно делать самому. Для некоторых классов копирование содержимого имеется(например TStringList, TBitmap), но у этих классов есть метод Assign, в котором прописано - что и как копируется/присваивается. Удачи. | 
| Этот пользователь сказал Спасибо icWasya за это полезное сообщение: | ||
|  
Velz (03.04.2012)
 | ||
| 
			 
			#3  
			
			
			
			
		 | ||||||
| 
 | ||||||
|   К сожалению, использовать SetLength не выходит - установка таким образом длинны массива происходит только 1 раз, потом не меняет (не знаю с чем это связанно), поэтому и пришлось переходить на указатели и использовать выделение памяти. Поэтому в данном случае от PCommandStackElmt = ^TCommandStackElmt; избавиться не удается =( Код: 
 Код: 
 Таким образом, остался только вопрос с "безопасной" работой памяти в ReallocMem (ибо избавиться от него не удается). Пытался сделать конструкцию с GetMemory и дополнительным указателем, с последующим копированием данных и переприсвоением указателя: Код: 
 | 
| 
			 
			#4  
			
			
			
			
		 | |||
| 
 | |||
|   >установка таким образом длинны массива происходит только 1 раз Что значит не меняет, - это как Вы делаете? А если хотите работать через GetMem, RealocMem, FreeMem? то нельзя использовать динамический массив (array of) >нужно будет массив указателей А как я уже говорил в Дельфи экземпляры классов итак указатели. | 
| Этот пользователь сказал Спасибо icWasya за это полезное сообщение: | ||
|  
Velz (03.04.2012)
 | ||
| 
			 
			#5  
			
			
			
			
		 | |||
| 
 | |||
|   Цитата: 
 Цитата: 
 Последний раз редактировалось Velz, 03.04.2012 в 09:59. | 
| 
			 
			#6  
			
			
			
			
		 | |||
| 
 | |||
|   вот это PCommandStack[Self.FCount].@Command вообще не должно скомпилироваться, А вот это PCommandStack[Self.FCount].Command:=ICommand; PCommandStack[Self.FCount].Command:=@ICommand; одно и то же. И ещё раз: если работаете с GetMem, ReallocMem, FreeMem, то нельзя использовать динамический массив. Надо тогда делать так TCommandStackElmt = array[0 .. MaxInt div 4-1] of TCommandStackElement; PCommandStackElmt = ^TCommandStackElmt; и не использовать SetLength никогда | 
| 
			 
			#7  
			
			
			
			
		 | |||
| 
 | |||
|   Цитата: 
 GetMem, ReallocMem, FreeMem и SetLength использовал только в различных типах данных (1е с указателем на массив, 2е при работе непосредственно с массивом). Вопрос: TCommandStackElmt = array[0 .. MaxInt div 4-1] of TCommandStackElement; это фиксированный массив по константе? Если да, то возможно ли сделать динамический массив из PCommandStackElmt? Или вообще сделать динамический массив указателей: Код: 
 | 
| 
			 
			#8  
			
			
			
			
		 | ||||
| 
 | ||||
|   я же говорю TCommandStackElmt = array[0 .. MaxInt div 4-1] of TCommandStackElement; PCommandStackElmt = ^TCommandStackElmt; Размер указан толькол для обмана компилятора - что бы не ругался на границу массива. Вы же нигде не будете использовать переменные типа TCommandStackElmt.( я надеюсь  а работать так Код: 
 Ещё раз для тех кто в танке если написали Код: 
  | 
| 
			 
			#9  
			
			
			
			
		 | |||
| 
 | |||
|   ObjectList из модуля Contnrs и никаких проблем только надо свойство OwnsObjects иметь ввиду, если не надо, чтобы он сам освобождал элементы, при их удалении я бы сделал так: PHP код: 
		 | 
| 
			 
			#10  
			
			
			
			
		 | |||||||
| 
 | |||||||
|   Цитата: 
 Уххх... в общем получилось все сделать   Итоговая конструкция осталась изначальной: Код: 
 Увеличение массива происходит через SetLength(PACommandStack^,FCount); присвоение данных через PACommandStack^[FCount-1].Command:=ICommand; так-же без проблем. А косяк обнаружился в теле основной программы - после выполнения AddNew (ICommand: TCommand), технично вызывался деструктор того, что уходило в ICommand... В общем весь косяк был в том, что я изначально не знал о "указательной" природе классов, и удалял тот-же самый элемент, который только только забил в массив. P.S. Называется хотел как лучше (раз создал объект - будь добр в конце удалить, дабы не мешался в памяти), а получилось через ... Спасибо  | 
| 
			 
			#11  
			
			
			
			
		 | |||
| 
 | |||
|   Ну так вернёмся к моему первому ответу - если SetLength заработал, тогда вот это PCommandStackElmt = ^TCommandStackElmt; - не нужно. используй прямо Код: 
 | 
| 
			 
			#12  
			
			
			
			
		 | |||||
| 
 | |||||
|   Цитата: 
 Код: 
 P.S. Деструктор все-равно делать, вот только в какой момент и к кому его прикручивать... но это уже другая тема =) Последний раз редактировалось Velz, 03.04.2012 в 17:01. |