2008-11-06 3 views
1

Исключение упоминаетЗачем `_getstream` терпеть неудачу?

FILE* __cdecl _getstream 

Я звоню fopen и он продолжает врезаться.

AfxMessageBox("getting here 1"); 
FILE* filePtr = fopen(fileName, "rb"); 
AfxMessageBox("getting here 2"); 

По какой-то причине я никогда не попадаю во второе поле сообщения. Интересно, что когда я в режиме отладки, приложение работает отлично. Зачем?

+0

Я почти подозревает разрешения, связанные проблемы. Запуск в режиме отладки означает повышение? Какая ОС и какая среда разработки? – cfeduke 2008-11-06 02:25:01

+0

Что такое «FILE * __cdecl _getstream» в верхней части вашего сообщения? Кроме того, вам не нужны скобки вокруг «rb». – paxdiablo 2008-11-06 02:53:31

ответ

-1

Я думаю, что что-то не так с именем (у него есть последний ноль?)

Попробовать комментарий Еорепа линии и посмотреть, что произойдет.

0

Я подозреваю, что с этой частью вашей программы нет ничего плохого. Наиболее вероятный сценарий заключается в том, что раньше у вас было какое-то повреждение памяти в коде, и именно так оно и происходит.

Вы пробовали запустить его через остальную часть программы (после этой части) в режиме отладки? Если это - - это некоторая искажение памяти, распределитель режима отладки должен поймать его, когда он пойдет, чтобы освободить поврежденные области памяти, если не раньше. Предполагая, что вы используете компилятор с полным распределителем памяти для отладки, конечно.

2

Я думаю, что повреждение памяти. В Windows (который __cdecl заставляет меня думать, что вы используете), есть утилита gflags, которая поставляется с инструментами для отладки Windows. С его помощью вы можете сделать каждое распределение кучи своей собственной страницей - это поможет перехватить перехват памяти и мгновенное освобождение сразу в точке проблемы.

Я написал инструкции на моем блоге:

http://www.atalasoft.com/cs/blogs/loufranco/archive/2007/02/06/6-_2200_Pointers_2200_-on-Debugging-Unmanaged-Code.aspx

Есть другие советы по поиску такого рода ошибки там тоже.

0

Я сомневаюсь, что это будет влиять на многих людей, так как это довольно неясными, но если вы получите ваш FILE *, как это:

HANDLE hMyFile = CreateFile(...); 
FILE* pFile = _fdopen(_open_osfhandle((long)hMyFile, <flags>), "rb"); 
CloseHandle(hMyFile); 

Тогда вы будете течь поток для каждого файла, открыт. После выполнения _open_osfhandle и _fdopen, вы должны вызвать fclose() в pFile, чтобы закрыть ваш дескриптор. CloseHandle, по-видимому, недостаточно умен, чтобы освободить рывок, который fdopen ассоциирует с вашей ручкой, но fclose достаточно умен, чтобы закрыть вашу ручку вместе с FILE * -соединенным слоем.

Приложение, над которым я работал, выполнило это, потому что определенный API прошел вокруг HANDLE, а конкретному разработчику API был необходим FILE *, поэтому разработчик сделал файл _fdopen/_open_osfhandle, чтобы получить файл *. Однако это означало, что вызов CloseHandle вызывающего абонента был недостаточным для полного закрытия HANDLE. Исправление заключалось в том, чтобы сначала перенести входящую HANDLE, а затем код FILE * мог правильно fclose() FILE *, не нарушая HANDLE вызывающего абонента.

Sample неработающая программа:

#include "stdafx.h" 
#include <Windows.h> 
#include <io.h> 
#include <assert.h> 
#include <fcntl.h> 
int _tmain(int argc, _TCHAR* argv[]) 
{ 

    for(int x = 0;x < 1024; x++) 
    { 
    HANDLE hFile = CreateFile(L"c:\\temp\\rawdata.txt",GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL); 
    FILE* pFile = _fdopen(_open_osfhandle((long)hFile, _O_RDONLY | _O_BINARY), "rb"); 
    assert(pFile); // this assert will go off at x=509, because _getstream() only has 512 streams, and 3 are reserved for stdin/stdout/stderr 
    CloseHandle(hFile); 
    } 

    return 0; 
}