Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2009.06.21;
Скачать: [xml.tar.bz2];

Вниз

Ошибка при освобождении памяти выделенной переменной Pointer   Найти похожие ветки 

 
ford ©   (2009-05-04 23:33) [0]

Помогите найти ошибку.
вот кусок кода

Type TData=Array[1..5] of Int64;
       TRecStruct=record
        ...
        Data:TData;
       end;

function TDataFile.ReadData(p:Int64; bCount:Integer):Pointer;
Var buf:Pointer;
    f:TFileStream;
    rec:TRecStruct;
Begin
...
f.Seek(p,soFromBeggining);
...
GetMem(buf,SizeOf(TData));
f.Read(rec,SizeOf(TRecStruct));
move(Pointer(@rec.data[1])^,Pointer(Int64(buf))^,SizeOf(TRec));
bCount:=SizeOf(TRec)
result:=buf;
End;

читается из файла структура, выделяется память пременной куда
копируются считанные данные и возвращается указатель на эти данные

далее в другой процедуре
Procedure Append(s:String);
Var ss:Pointer;
    buf:Array of Int64;
    dd:^Int64;
    p:Int64;
    bCount:Integer;
...
      //читаем данные и получаем указатель на них
      ss:=DataF.ReadData(p,bCount);
      //в данной процедуре я хочу их интерпретировать как массив Int64
      buf:=ss; //<----
      Buf[0]:=buf[0]+1;
      //dd:=ss;
      //dd^:=dd^+1;
      //записываем данные обратно в файл в пизицию Р
      DataF.WriteData(p,ss,SizeOf(TRec));
      //освобождаем память
      FreeMem(ss);
end;
-----------------

ничего особенного, читаем данные из файла с позиции P в буфер
пытаемся использовать данные как массив Int64
изменяем первый элемент массива
записываем данные обратно в файл и собственно освобождаем указатель
пару раз отрабатывает нормально
на третий разрушаются переменные которые были переданны процедуре
например S изначально имеет значение "ПРИВЕТ"
после строки buf:=ss; её значение изменяется на
что-то типа "ПРИВЕТ"+#0+#0+"W"+#0+#0.....
и при попытке освободить память в строке
FreeMem(ss);
вылетает AcessViolation
ежели я закоментирую строки с buf:=ss; buf[0]:=buf[0]+1;
и откоментирую другие там где dd:=ss; dd^:=dd^+1;
то все проходит нормально хоть вызывай эту процедуру 1000 раз
:((

я понимаю что гдето я переписываю не ту память
но немогу найти хоть тресни

помогите, подскажите где ошибка


 
palva ©   (2009-05-04 23:55) [1]


> move(Pointer(@rec.data[1])^,Pointer(Int64(buf))^,SizeOf(TRec));

Честно говоря, напрягают такие параметры, неужели нельзя попроще. Да и TRect не понятно откуда взялось.


 
palva ©   (2009-05-05 00:03) [2]


> Да и TRect не понятно откуда взялось.

Пардон, Как раз TRect понятно, что такое. У вас нигде не описанный идентификатор TRec.


 
palva ©   (2009-05-05 00:05) [3]

Правда к делу это отношения не имеет.


 
ford ©   (2009-05-05 00:14) [4]


> TRect не понятно откуда взялось.

не TRec  ессесно а TData
уже три варианта переписал
не тот кусок вставил
но смысл не меняется


> неужели нельзя попроще

незнаю может и можно
есть файл хранилище в котором хранятся структуры и массивы
и класс контейнер для всего этого добра который просто читает кусок файла и передает дальше
а кто просил тот и решает как его интерпретировать
т.е. контейнер инкапсулирует в себе все функции чтения записи/данных
поэтому в контейнере запись файла содержит в себе некоторую информацию необходимую для него и собственно сами данные которые записываюся
структура TRecStruct
и собственно данные которые туда пишутся поле Data

я уже упростил и сделал просто массив целых
и передаю туда и читаю из него


 
Игорь Шевченко ©   (2009-05-05 00:19) [5]

То есть, ты присваиваешь некий свой pointer динамическому массиву и удивляешься, что происходят ошибки ?

Я бы не удивлялся.


 
ford ©   (2009-05-05 00:23) [6]


> То есть, ты присваиваешь некий свой pointer динамическому
> массиву и удивляешься, что происходят ошибки ?
>
> Я бы не удивлялся.

а как тогда ??
со структурами все классно
TAnyStruct(ss).Field:=100;

а вот с массивами .....


 
ford ©   (2009-05-05 00:35) [7]

получилось только таким образом
Type TBigArray=Array[1..1000] of Int64;

и в программе
TBigArray(ss^)[1]:=TBigArray(ss^)[1]+1;

выглядит конечно белокоренно но работает
:(


 
sniknik ©   (2009-05-05 01:26) [8]

> То есть, ты присваиваешь некий свой pointer динамическому массиву
он думает что это одно и то же. начитаются разного... ->  
http://delphimaster.net/view/2-1241089539/
> вполне себе динамический массив.


 
ford ©   (2009-05-05 02:29) [9]


> sniknik ©

в Си это делается просто без всяких вывертов и наворотов
там ежели это указатель то разадресовывай его как хочешь
а тут млин
Массив это такой указатель
динамический массив это другой указатель
т.е. ты не смотри что массив в памяти храниться последовательно
что в первом что в другом случае и что собственно говоря что там что там переменная это не что иное как адрес перового элемента
неее ты сломай мозг :) вывернись наизнанку
в реале пришлось сделать
for i:=1 to BCount div SizeOf(Integer) do
Integer(Integer(ss)+SizeOf(Integer)*(i-1))^:=10

это так, для разминки, чтобы присвоить всем прочтенным элементам массива значение 10
:))

и к стати я от тебя не увидел ни какого красивого решения данной задачи


 
ford ©   (2009-05-05 02:36) [10]


> sniknik ©   (05.05.09 01:26) [8]
>
> > То есть, ты присваиваешь некий свой pointer динамическому
> массиву
> он думает что это одно и то же. начитаются разного... ->
>  
> http://delphimaster.net/view/2-1241089539/
> > вполне себе динамический массив.

вообще прикольно наверное, пробежав вопрос, не вникнув в КОД указанный выше и описание к нему
ляпнуть абы-что, типа "пометить" - "тут был Вася"
:))


 
Servy ©   (2009-05-05 03:27) [11]

> в Си это делается просто без всяких вывертов и наворотов
>
> там ежели это указатель то разадресовывай его как хочешь

Ты не поверишь, в Делфи ровно также.


> Массив это такой указатель

Массив - это массив, и ничего более.


> динамический массив это другой указатель

Динамический массив в делфи - это особый тип данных, финализируемый компилятором. Назвать его просто указателем - неверно.


> т.е. ты не смотри что массив в памяти храниться последовательно
>
> что в первом что в другом случае и что собственно говоря
> что там что там переменная это не что иное как адрес перового
> элемента

Есть существенная разница - на что указывает этот, как вам нравится его называть, указатель. Как уже упоминалось, динамический массив - особый тип данных, и если вы не работаете с ним так, как ожидает компилятор - предполагается, что вы знаете, что делаете. В вашем случае - вы, видимо, не знаете. А должны бы знать, в хелпе все хорошо описано.

Все просто: если вам нужен указатель - используйте указатель. Если вам нужен динамический массив - используйте динамический массив. Если вам нужен указатель на массив - используйте указатель на массив.


> неее ты сломай мозг :) вывернись наизнанку

У плохого мастера инструмент виноват :).

Ваш код написан в сишном стиле - непонятные двухбуквенные переменные, кучи действий без комментариев и необходимости в них. Для примера, было бы интересно узнать, зачем могло понадобится Pointer(Int64(buf))^ - приводить указатель к Int64, а потом назад. В общем, это WriteOnly код - написал, работает, забыл. Другому человеку (или самому себе через полгода) в нем разбираться - дело очень неблагодарное, так что и мне заниматься им не слишком-то охота ^_^.


> в реале пришлось сделать
> for i:=1 to BCount div SizeOf(Integer) do
> Integer(Integer(ss)+SizeOf(Integer)*(i-1))^:=10

Этот код даже не скомпилируется, так как тип Integer нельзя разыменовать.

Возможно, вам нужно что-то вроде:


type
 TInt64Array = array [0..268435454] of Int64;
 PInt64Array = ^TInt64Array;

var
 Buf: PInt64Array;


В этом случае, Buf будет указателем на массив, чего вы, судя по всему, и хотели. Однако, в вашем коде вполне могут быть другие ошибки, который при таком стиле написания обнаружить будет ой как непросто. Но это уже ваше дело :).


> вообще прикольно наверное, пробежав вопрос, не вникнув в
> КОД указанный выше и описание к нему
> ляпнуть абы-что, типа "пометить" - "тут был Вася"

Мне показалось, что пост [8] кратко и по-существу описывает возникшую у вас проблему - то, что под динамическим массивом вы понимаете что-то иное, а не то, что разработчики делфи описали в хелпе в разделе dynamic arrays. Впрочем, вам некого в этом винить, кроме как самого себя ^_^.


 
Игорь Шевченко ©   (2009-05-05 11:43) [12]

ford ©   (05.05.09 02:29) [9]


> и к стати я от тебя не увидел ни какого красивого решения
> данной задачи


вообще-то решение задачи должно быть от тебя, вроде как твоя задача.



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

Форум: "Начинающим";
Текущий архив: 2009.06.21;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.51 MB
Время: 0.006 c
15-1239481803
Юрий
2009-04-12 00:30
2009.06.21
С Днём рождения ! 12 апреля 2009 воскресенье


2-1240930943
granddad
2009-04-28 19:02
2009.06.21
Методы контроля своевременного освобождения памяти


2-1241502567
iiunbreakableii
2009-05-05 09:49
2009.06.21
координаты выделенного текста в Richedit


15-1239357142
Kostafey
2009-04-10 13:52
2009.06.21
Посоветуйте почтовую программу


4-1191555720
ter
2007-10-05 07:42
2009.06.21
WM_DEVICECHANGE или как определить безопасное извлечение флэшки





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