Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Освобождение памяти [D7, WinXP]


Страницы:   1 2

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й строке.


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо