Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Общие вопросы > Помогите найти ошибку


Автор: Illusion Dolphin 10.8.2004, 19:23
Люди! Человеки! Которую неделю видел в программе один странный глюк, но всё руки не доходили, а теперь дошли :/... День сидел в отладке и поисках - ноль по фазе. В общем - ошибка при работе с памятью (90% - все симптомы). Не удаётся выделить тот кусок программы, который даёт ошибку, поэтому я её обрезал до "необходимого минимума ошибки":

http://www.illusdolphin.narod.ru/test.zip

Пожалуйста, посмотрите, в чём дело. Компилировал на делфи7. Для того, чтобы произошла ошибка нужно создать папку "C:\Dolphin\1\234' (да можно любое, просто по умолчанию такая была smile.gif, хотя последнее имя (234) - вообще не имеет значения). После запуска программы появится окно мини-проводника, где будет видна одна папка - "234" (т.к. папка по умолчанию - "C:\Dolphin\1"). нужно выделить эту единственную папку, нажать на F2 и переименовать в любое другое имя. После этого или вылазит ошибка или всё просиходит молча, но если снять выделение с папки и опять выделить её, то появится имя "%SystemRoot%\System23\Shell32.dll" (%SystemRoot% - папка винды). Откуда берётся ошибка? ПОЖАЛУЙСТА, КТО ХОРОШО ЗНАЕТ ДЕЛФИ -- ПОСМОТРИТЕ, пожалуйста!

Автор: p0s0l 10.8.2004, 21:19
Немного глянул...
Цитата
"%SystemRoot%\System23\Shell32.dll"

Это происходит на ExtractAssociatedIcon - посмотри недавние темы, была темка про ошибку в этой функции (она изменяет FileName, хотя не должна... sad.gif)
Цитата
нажать на F2 и переименовать в любое другое имя. После этого или вылазит ошибка

Если закомментировать строку:
TExplorerThreadNotifyDirectoryChange.Create(False,s,DirectoryChanged,CurrentGUID,@CurrentGUID);
то ошибки не происходит, видимо ошибка тут...
Если присмотреться, то сомнительным кажется код:
Код
  FileName:='';
  GetMem(FileName,PFileNotifyInformation(Ptr).FileNameLength + 2);
  ZeroMemory(FileName,PFileNotifyInformation(Ptr).FileNameLength*4 + 2);
  lstrcpynW(FileName,PFileNotifyInformation(Ptr).FileName, PFileNotifyInformation(Ptr).FileNameLength div 2+1);
  SFileName:=FileName;
  FreeMem(FileName);

Выделяется памяти FileNameLength + 2, а обнуляется в 4 раза больше...
А я делал так, чтобы особо не мудрить:
Код

  SetLength (ws, PFileNotifyInformation(Ptr).FileNameLength div 2);
  CopyMemory (@ws[1], @PFileNotifyInformation(Ptr).FileName, PFileNotifyInformation(Ptr).FileNameLength);
  SFileName := ws;
(ws : WideString);
Заменив этот код , и убрав этот кусок:
Код
{     ico:=TIcon.Create;
    Ico.Handle:=ExtractAssociatedIcon(HInstance, PChar(FileName), IconIndex);
    Canvas.Draw(ThImageSize div 2-Ico.Width div 2,ThImageSize div 2-Ico.Height div 2,Ico);
    Ico.free;}

Ошибок больше не вылазило, но почему-то переименование отлавливается только 1 раз... Это видимо уже где-то логическая ошибка...

Автор: Illusion Dolphin 10.8.2004, 22:16
Цитата
Это происходит на ExtractAssociatedIcon - посмотри недавние темы, была темка про ошибку в этой функции (она изменяет FileName, хотя не должна... )

Да, это один из "интересных мест". действительно, с этой функцией были неполадки (я это давно заметил, но в связи с тем, что это не единственное место такого типа, не убирал его). Я поищу на эту тему справку. А в чём точно эта ошибка выражается? Почему она лезет совсем в "левую" память?

Цитата
Выделяется памяти FileNameLength + 2, а обнуляется в 4 раза больше...

Это всё норма, это я уже начал "мудрить" с горя (проблвал преувеличить ошибку, если она тут 8) ). Там 4-ки нет. Этот модуль без ошибки (я ещё более упростил проект, уже вообще полупустая прога, но с ошибкой 8)...).

P.S. нашёл топик по ExtractAssociatedIcon... это по-моему то, что и было...

Автор: Петрович 11.8.2004, 09:08
Цитата(p0s0l @ 10.8.2004, 21:19)
Это происходит на ExtractAssociatedIcon - посмотри недавние темы, была темка про ошибку в этой функции (она изменяет FileName, хотя не должна... )

Это не ошибка!
Читайте MSDN:
Цитата
lpIconPath
[in] Pointer to a string that specifies the full path and file name of the file that contains the icon. The function extracts the icon handle from that file, or from an executable file associated with that file.
If the icon handle is obtained from an executable file, the function stores the full path and file name of that executable in the string pointed to by lpIconPath.


to Illusion Dolphin
Цитата
Да, это один из "интересных мест". действительно, с этой функцией были неполадки (я это давно заметил, но в связи с тем, что это не единственное место такого типа, не убирал его). Я поищу на эту тему справку. А в чём точно эта ошибка выражается? Почему она лезет совсем в "левую" память?

Поищи, то ли здесь, то ли на сорсах я об этом уже писал.
Если кратко, то:
ExtractAssociatedIcon в lpIconPath возвращает измененный путь. Причем, иногда, как в твоем случае этот путь длинее чем тот который ты ему передал. Вот ExtractAssociatedIcon и вылезает за пределы той памяти гда у тебя размещался путь передаваемый в него.
Надо перед вызовом ExtractAssociatedIcon создать буфер размером MAX_PATH символов (+1 для завершающего #0), скопировать туда твой путь, и именно этот буфер передавать в ExtractAssociatedIcon.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)