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

Вниз

Ошибка при освобождении памяти выделенной переменной 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;
Скачать: CL | DM;

Наверх




Память: 0.51 MB
Время: 0.014 c
15-1239913802
Юрий
2009-04-17 00:30
2009.06.21
С днем рождения ! 17 апреля 2009 пятница


1-1211449928
Сергей М.
2008-05-22 13:52
2009.06.21
IntraWeb5 - TIWControl.Font


6-1203662268
Артем
2008-02-22 09:37
2009.06.21
проблема отображения картинок в WebBrowser


2-1240998993
AG
2009-04-29 13:56
2009.06.21
Delphi, матрицы


15-1239395408
Юрий
2009-04-11 00:30
2009.06.21
С Днём рождения ! 11 апреля 2009 суббота