Большой Воронежский Форум
» Программирование>Ошибка Access violation
$@#Y@ 21:58 04.03.2008
Есть такой вот кусок кода на сях...
С++ Builder 6...
При попытке открыть какой-то файл прога вылетает с ошибкой Access violation на строке красного цвета...

Сообщение от :
int p;
void* lpFile;
_IMAGE_FILE_HEADER *tmp_file_header;

OpenDialog->Execute();
if (OpenDialog->FileName=="") return;
{


p = OpenFile((OpenDialog->FileName.c_str()),NULL,OF_READ);
lpFile = CreateFileMapping((void*)p, OF_READ, 0,0,0,NULL);
MapViewOfFile(lpFile,FILE_MAP_READ,0,0,0);
tmp_file_header=(PIMAGE_FILE_HEADER)PEFHDROFFSET (lpFile);

Machine_Label->Caption=((PIMAGE_FILE_HEADER)
PEFHDROFFSET (lpFile))->Machine;

//выгружаем и закрываем файл
UnmapViewOfFile(lpFile);
CloseHandle(lpFile);
CloseHandle((void*)p);
}

А точнее, в этой строке файла dstring.h

Сообщение от :
char* __fastcall c_str() const { return (Data)? Data: "";}

Что неправильно в приведенном куске кода? [Ответ]
Part!zan 20:52 05.03.2008
$@#Y@, ну смотри, что в FileName лежит и делай выводы. [Ответ]
$@#Y@ 21:11 05.03.2008
Part!zan, там все правильно лежит.... Полный путь к файлу в AnsiString... [Ответ]
Yandex 21:24 05.03.2008

Сообщение от :
if (OpenDialog->FileName=="") return;
{
...
}

Я С++ не очень знаю, но че та какой то return странный... else что ли дописать. [Ответ]
Part!zan 00:18 06.03.2008
$@#Y@, если там все правильно лежит, то и аксес виолешн не должно быть. Смотри какой указатель возвращает с_str.

Yandex, да не, так можно, хоть и странно написано. ) [Ответ]
$@#Y@ 19:08 06.03.2008
Part!zan, указатель на массив с путем к файлу, примерно вот так. С виду все нормально, указатель на нужную строку.
В скрине смущает то, что одиночные слеши в пути к файлу заменены на двойные. Но если попросить мессаджбокс с этой строкой - то слеши будут одинарные...

ЗЫ. Начал программить в си после дельфей, не пинайте, многих особенностей языка не знаю...
Изображения
Нажмите на изображение для увеличения
Название: scrn.JPG
Просмотров: 31
Размер:	136.5 Кб
ID:	237548  
[Ответ]
$@#Y@ 19:51 06.03.2008
Кстати, только сейчас нашел, что аксес виолейшн-то у меня вообще в модуле kernel32.dll... Это что значит?
Изображения
Нажмите на изображение для увеличения
Название: Безымянный.JPG
Просмотров: 15
Размер:	18.0 Кб
ID:	237584  
[Ответ]
Part!zan 19:53 06.03.2008

Сообщение от $@#Y@:
смущает то, что одиночные слеши в пути к файлу заменены на двойные

Мдя, далеко ты стакими познаниями не уедешь. Книжки, что ли почитай. За пару часов все особенности С можно усвоить.

Сообщение от $@#Y@:
если попросить мессаджбокс с этой строкой

То есть, месседжбокс с OpenDialog->FileName.c_str() работает нормально?

Сообщение от $@#Y@:
в модуле kernel32.dll

Ниче удивительного. Апишные функции все-таки используются иногда. ) Только непонятно причем тут c_str. [Ответ]
$@#Y@ 19:59 06.03.2008

Сообщение от Part!zan:
То есть, месседжбокс с OpenDialog->FileName.c_str() работает нормально?

Да, работает отлично. [Ответ]
Dao 20:46 06.03.2008
В строке "OpenFile((OpenDialog->FileName.c_str()),NULL,OF_READ);"
NULL - точно правильно стоит? Вроде там нужен указатель: OFSTRUCT ofs;
"OpenFile((OpenDialog->FileName.c_str()),&ofs,OF_READ);" [Ответ]
$@#Y@ 20:52 06.03.2008

Сообщение от Dao:
В строке "OpenFile((OpenDialog->FileName.c_str()),NULL,OF_READ);"
NULL - точно правильно стоит? Вроде там нужен указатель: OFSTRUCT ofs;
"OpenFile((OpenDialog->FileName.c_str()),&ofs,OF_READ);"

Поправил, спасибо.
Теперь аксес виолейшн в другой строке...

Сообщение от :
tmp_file_header=(PIMAGE_FILE_HEADER)PEFHDROFFSET (lpFile);

[Ответ]
Yandex 22:49 06.03.2008
$@#Y@, гы-гы, может стоит скопировать пример с борландовского мана или MSDN? [Ответ]
$@#Y@ 07:59 07.03.2008
Yandex, да, надо бы... где бы их взять только... [Ответ]
J++ 10:54 07.03.2008
К сожалению, возможна ошибка не в этом месте, она здесь может только проявляться (если ты где-нибудь испортил память).

Копать можно до бесконечности, вплоть до действия методом "деления программы пополам с помощью комментов"

Попробуй для начала закомментарить почти весь код этого модуля кроме собственно открытия-закрытия файла, посмотри как сделано в примерах.
Или попробуй не вызывать диалог, а открыть заранее оговоренный файл.
[Ответ]
$@#Y@ 12:48 07.03.2008
J++, в этом модуле, как и во всей программе, этот кусок кода пока единственный...

Переписал на:

Сообщение от :
int p=0;
void* lpFile;
PIMAGE_FILE_HEADER tmp_file_header;
OFSTRUCT ofs;
unsigned long * lpFileSize;
OpenDialog->Execute();
if (OpenDialog->FileName=="") return;
{
//Application->MessageBoxA(OpenDialog->FileName.c_str(),NULL);
OpenDialog->FileName="D:\Programming\Delphi\Converter\Convert erProject.exe";
p = OpenFile((OpenDialog->FileName.c_str()),&ofs,OF_READ);
GetFileSize((void*)p, lpFileSize);
lpFile = CreateFileMapping((void*)p, OF_READ, PAGE_READWRITE,0,*lpFileSize,NULL);
Application->MessageBoxA(IntToStr(lpFile).c_str(),NULL);
MapViewOfFile(lpFile,FILE_MAP_READ,0,*lpFileSize,0 );
tmp_file_header=(PIMAGE_FILE_HEADER)PEFHDROFFSET (lpFile);

Получается, что указатель lpFile равен 0, это значит, что ошибка в функции CreateFileMapping... Какие-то из параметров неверны.. Исправил параметр этой функции dwMaximumSizeLow с 0 на размер открываемого файла. Но указатель lpFile по-прежнему равен 0... [Ответ]
Yandex 13:14 07.03.2008
Что значит где взять? Это вопрос где взять Builder без манов

Я в указателях не силен, но имхо ты что то не то делаешь.
Я бы попробовал что то вот в таком духе

Сообщение от :
HFILE hFile;
HANDLE hMapFile;
OFSTRUCT ofs;
...
hFile = OpenFile("D:\Programming\Delphi\Converter\Converte rProject.exe", ofs,OF_READ);
hMapFile = CreateFileMapping(hFile, OF_READ, PAGE_READWRITE,0,???, NULL);

P.S. Лень в манах ковыряться.
[Ответ]
$@#Y@ 13:32 07.03.2008
Теперь так.

Сообщение от :
void* p=0;
void* lpFile;
PIMAGE_FILE_HEADER tmp_file_header;
// OFSTRUCT ofs;
unsigned long * lpFileSize;
//OpenDialog->Execute();
//if (OpenDialog->FileName=="") return;
{
//Application->MessageBoxA(OpenDialog->FileName.c_str(),NULL);
OpenDialog->FileName="C:\KProject.exe";
p = CreateFile((OpenDialog->FileName.c_str()),OF_READ,0,0,
OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);

GetFileSize(p, lpFileSize);
lpFile = CreateFileMapping(p, OF_READ, PAGE_READWRITE,0,0,NULL);
Application->MessageBoxA(IntToStr(lpFile).c_str(),NULL);
MapViewOfFile(lpFile,FILE_MAP_READ,0,*lpFileSize,0 );
tmp_file_header=(PIMAGE_FILE_HEADER)PEFHDROFFSET (lpFile);

Machine_Label->Caption=((PIMAGE_FILE_HEADER)
PEFHDROFFSET (lpFile))->Machine;

Указатель р не равен 0, значит, файл открыт. А вот lpFile равен 0, не получается файл отобразить... [Ответ]
$@#Y@ 15:10 07.03.2008
Переложил код заново.

Сообщение от :
PIMAGE_FILE_HEADER tmp_file_header;

HANDLE hFile = CreateFile( "c:\KProject.exe" , GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL);


HANDLE hFileMapping = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);

MapViewOfFile(hFileMapping,FILE_MAP_READ,0,0,0);
tmp_file_header = (PIMAGE_FILE_HEADER)PEFHDROFFSET (hFileMapping);

// Machine_Label->Caption=((PIMAGE_FILE_HEADER)
// PEFHDROFFSET (hFileMapping))->Machine;

UnmapViewOfFile(hFileMapping);
CloseHandle(hFileMapping);
CloseHandle(hFile);

Аксес виолейшн выскакивает в строке

Сообщение от :
tmp_file_header = (PIMAGE_FILE_HEADER)PEFHDROFFSET (hFileMapping);

Блиа...
Все три указателя у нас NULL... [Ответ]
$@#Y@ 15:43 07.03.2008
Начнем сначала.

Сообщение от :
HANDLE hFile = CreateFile( "С:\KProject.exe" , GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL);

Йоптваю....
Гр****ая закорючка в пути к файлу была причиной всех ошибок...
Неверный путь к файлу=> нулевой указатель на файл=> остальные указатели тоже нулевые=> некорректное обращение к памяти=>аксесс виолейшн... [Ответ]
Part!zan 23:02 07.03.2008

Сообщение от $@#Y@:
смущает то, что одиночные слеши в пути к файлу заменены на двойные

Сообщение от $@#Y@:
закорючка в пути к файлу была причиной всех ошибок

Я ж те говорил, книжку почитай. Блин, любители программить методом тыка... [Ответ]
$@#Y@ 09:07 08.03.2008
Part!zan, не, ты не понял...
Я переписал код на:

Сообщение от :
PIMAGE_FILE_HEADER tmp_file_header;

HANDLE hFile = CreateFile( "c:\KProject.exe" , GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL);


HANDLE hFileMapping = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);

MapViewOfFile(hFileMapping,FILE_MAP_READ,0,0,0);
tmp_file_header = (PIMAGE_FILE_HEADER)PEFHDROFFSET (hFileMapping);

// Machine_Label->Caption=((PIMAGE_FILE_HEADER)
// PEFHDROFFSET (hFileMapping))->Machine;

UnmapViewOfFile(hFileMapping);
CloseHandle(hFileMapping);
CloseHandle(hFile);

И вот в пути к файлу

Сообщение от :
"c:\KProject.exe"

у меня вместо буквы "С" стоял другой символ, похожий на букву N с тильдой сверху... Я хз, как в пути файла оказался этот символ, но все было из-за него... А нашел его так - вставил код копипастом в форму ответа на форуме и там уже увидел эту закорючку... Потом поменял ее на букву C и все заработало... [Ответ]
Part!zan 14:28 08.03.2008
$@#Y@, короче, я тебе говорю, что строка "c:\KProject.exe" - это вовсе c:\KProject.exe, а непойми что. Слэши должны дублироваться: "c:\\KProject.exe". Как оно у тебя работает - загадка. [Ответ]
Ivan XXX 21:05 11.03.2008

Сообщение от $@#Y@:
Неверный путь к файлу=> нулевой указатель на файл=> остальные указатели тоже нулевые=> некорректное обращение к памяти=>аксесс виолейшн...

все правильно указатель есть, но указывает он "вникуда" )
перед использованием необходимо делать проверку на нулл. пример:

double * pf; // 4 байта на указатель выделились, но указывают они хрен знает куда на 8 байт )
if ( pf != NULL )
{
cout << * pf << endl;
}
else
{
cout << "pf == NULL" << endl;
}

типа того ) [Ответ]
Вверх