![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Освобождение памяти [D7, WinXP]
KygECHuK © (2006-04-14 20:21:00)При освобождении памяти, занятой при помощи функций GetMem или StrAlloc иногда у меня возникает ошибка доступа памяти. В чём может скрываться ошибка ?
Сергей М. (2006-04-18 16:41:00) [1]
> GrayFace © (18.04.06 16:35) [25]
> первые два условия выполнены
Сомневаюсь что при i = 0 это условие когда-либо было бы выполнено ..
Да и AV тот самый возник бы (но вовсе необязательно) на этом операторе, который заведомо раньше по тексту, чем StrDispose(), именно на который столь упорно жалуется автор.
GrayFace (2006-04-18 16:35:00) [2]А зачам, вообще, использовать StrAlloc и StrDispose? Чем, например, GetMem не угодил? Или обычные строки/дин. массивы?
> if (int64(pointer(@P[i])^) = int64(pointer(@P[i + 8])^)) and
> (int64(pointer(@P[i])^) <> 0) and ((int64(pointer(@p[i - 8])^)) = Signature) then
Несабжевая ошибка: если i=0 и первые два условия выполнены, залезешь в p-8.
KygECHuK (2006-04-18 12:45:00) [3]Удалено модератором
Примечание: Создание пустых сообщений
KygECHuK (2006-04-18 12:45:00) [4]Удалено модератором
KygECHuK (2006-04-18 12:45:00) [5]Когда ошибка появлялась я исследовал код отладчиком и именно строка с StrDispose оказалась причиной этого.
Завтра я постараюсь раздабыть тод код на каторой я жаловался в самом начале, но там ошибка такая же.
Сергей М. (2006-04-18 12:30:00) [6]Хорошо, ну тогда на основании чего ты сделал умозаключение о возникновении отказа именно при выполнении StrDispose() ?
KygECHuK (2006-04-18 12:22:00) [7]Адский сатанизм, щас ошибка не появляется, но я уверен она как всегда выскочит в самый неблагоприятный момент. Так было всегда
KygECHuK (2006-04-18 12:10:00) [8]>> Сергей М.
>> Есть подозрение, что где-то между StrAlloc и StrDispose ты гадишь в стеке
Нет, программа удачно копирует содержимое из памяти в файл после CopyMemory()
Сергей М. (2006-04-18 12:08:00) [9]
> Вопрос - ПОЧЕМУ !?
Потому что потому.
Отладчиком пользоваться не пробовал ?
Еше раз : первое что следует сделать для поиска ошибки - это сравнить значение p, полученное при StrAlloc, со значением p, передаваемым в StrDispose
Сергей М. (2006-04-18 12:06:00) [10]Есть подозрение, что где-то между StrAlloc и StrDispose ты гадишь в стеке, где хранится в т.ч. значение p. И подозрение это падает, скорей всего, на CopyMemory().
KygECHuK (2006-04-18 12:06:00) [11]ReAlloc пока забыли. ситуация состоит в следующем:
при малых размерах файла программа не выдаёт ошибок, а при больших - выдаёт. Вопрос - ПОЧЕМУ !?
KygECHuK (2006-04-18 12:02:00) [12]Удалено модератором
Примечание: Создание пустых сообщений
Сергей М. (2006-04-18 11:59:00) [13]Ну и где здесь "смена длины" ?
Смена длины - это realloc-операция, а у тебя ее нигде нет. Так что в заблуждение вводишь ..
> тупо освобождаю память
Надо бы не "тупо освобождать", а под отладчиком внимательно сравнить значение p, полученное при StrAlloc, со значением p, передаваемым в StrDispose. Для начала хотя бы ..
KygECHuK (2006-04-18 11:29:00) [14]пример немного другоу но проблема та же:
function ChangeFileVers(FileName: string; Ma, Mi, Re, Bu: word): integer;
const
Signature = 281479253787837;
var
filestream : TFileStream;
i,l,pos1 : Integer;
Ver : Array[1..4] of word;
Fstr : String;
P : Pchar;
FSize : Integer;
begin
begin
Result := 0;
if not FileExists(FileName) then
begin
Result := -2;
exit;
end;
try
filestream := TFileStream.Create(FileName,fmOpenReadWrite);
p := pointer(StrAlloc(filestream.Size + 1));
try
filestream.Read(pointer(p)^, filestream.Size);
pos1 := -1;
FSize := filestream.Size;
l := filestream.Size - 9;
for i := 0 to l do
if (int64(pointer(@P[i])^) = int64(pointer(@P[i + 8])^)) and
(int64(pointer(@P[i])^) <> 0) and ((int64(pointer(@p[i - 8])^)) = Signature) then
begin
if pos1 <> -1 then
begin
Result := -1;
exit;
end;
pos1 := i;
Result := 0;
end;
Ver[1] := Ma;
Ver[2] := Mi;
Ver[3] := Re;
Ver[4] := Bu;
Fstr := Fstr + pchar(@Ver)[2] + pchar(@Ver)[3] ;
Fstr := Fstr + pchar(@Ver)[0] + pchar(@Ver)[1] ;
Fstr := Fstr + pchar(@Ver)[6] + pchar(@Ver)[7] ;
Fstr := Fstr + pchar(@Ver)[4] + pchar(@Ver)[5] ;
Fstr := Fstr + pchar(@Ver)[2] + pchar(@Ver)[3] ;
Fstr := Fstr + pchar(@Ver)[0] + pchar(@Ver)[1] ;
Fstr := Fstr + pchar(@Ver)[6] + pchar(@Ver)[7] ;
Fstr := Fstr + pchar(@Ver)[4] + pchar(@Ver)[5] ;
CopyMemory(pointer(@P[pos1]), pointer(pchar(Fstr)),16);
filestream.Position := 0;
filestream.Size := 0;
filestream.Write(pointer(p)^, FSize)
finally
filestream.Free;
StrDispose(pointer(P)); // Вот тут появляется ошибка при работе
//с больши файлами. Понимаю, что код можно
//было сделать более оптимальным, но я ищу
//причину ошибки при освобождении больших
//объёмов памяти
end;
except
Result := GetLastError;
end;
end;
end;
balepa (2006-04-18 11:09:00) [15]KygECHuK © не все же KygECHuK'и и магией пользоваться не умеют что бы узнать что ты там написал
Anatoly Podgoretsky (2006-04-18 11:06:00) [16]KygECHuK © (18.04.06 10:35) [9]
Тебе же указали точное место ошибки - 17 строка.
Сергей М. (2006-04-18 10:47:00) [17]
> KygECHuK © (18.04.06 10:35) [9]
Показывай код
KygECHuK (2006-04-18 10:35:00) [18]Я не ссылайсь на прежний адресс буфера. Я тупо освобождаю память из под буффера и беру новый адресс с новой длинной. Вот в момент освобождения происходит ошибка.
Сергей М. (2006-04-18 10:24:00) [19]
> использую буффер памяти, очень часто меняя его длинну
В ряде случаев смена размера буфера, распределяемого динамически, ведет к смене адреса начала буфера. При реаллокации буфера с целью увеличения его размера полагаться на прежний адрес буфера нельзя.
Плохиш (2006-04-18 10:16:00) [20]Надо исправить ошибку в 17й строке.