Форум: "Начинающим";
Текущий архив: 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