xuyunhai20160827 Ответов: 2

Почему файл readfile API windows не получает нужного размера


<pre>DWORD errorNo = 0;
template <typename TYPE>
bool read(HANDLE hPipe,TYPE &data)
{
	DWORD size=sizeof(TYPE),dwBytesRead=0;
	bool ret=ReadFile(hPipe,&data,size,&dwBytesRead,NULL);
	errorNo = GetLastError();
	return ret;
}
bool readString(HANDLE hPipe,string &str)
{
	DWORD size,dwBytesRead=0;
	char *c;
	bool ret=read(hPipe,(int &)size);
	if(ret&&size>0  )
	{
		c=new char[size+1];
		ret=ReadFile(hPipe,c,size,&dwBytesRead,NULL);  //throw 0xC0000005 
		c[size]='\0';
		str= string(c);
	}
	return ret;
}



функция ReadFile бросает ошибку 0xC0000005, потому что функция read не может получить правильный размер,в большинстве случаев правильный размер может быть получен. Когда программа запускается сотни тысяч раз, иногда происходит сбой, чтобы получить правильный размер и вызвать ошибки.
как решить этот вопрос

Что я уже пробовал:

используйте GetLastError (), чтобы получить номер ошибки, но это число равно нулю.

2 Ответов

Рейтинг:
12

Jochen Arndt

Единственные возможные причины, которые приходят мне на ум, - это когда size является UINT_MAX (0xFFFFFFFF) или чтение длины строки прерывается завершением операции записи на конце канала записи.

Чтобы избежать последнего, используйте цикл для чтения:

bool read(HANDLE hPipe, TYPE &data)
{
    DWORD size = sizeof(TYPE);
    bool ret = true;
    char *buf = reinterpret_cast<char*>(&data);
    do
    {
        DWORD dwBytesRead = 0;
        ret = ReadFile(hPipe, buf, size, &dwBytesRead, NULL);
        buf += dwBytesRead;
        size -= dwBytesRead;
    } while (ret && size);
    return ret;
}


дополнительное Примечание:

Почему вы здесь снимаетесь?
bool ret=read(hPipe,(int &)size);
Когда приведение действительно необходимо (чего здесь нет), используйте приведения C++, а не C-приведения.

Вы забыли удалить его c так что у вас есть утечка памяти.


Рейтинг:
0

CPallini

ReadFile[^] не должен (и я почти уверен, что это не так) ничего бросать. Он может вернуться FALSE (и тогда вы должны немедленно позвонить GetLastError чтобы получить дополнительную информацию).

Обратите внимание, что ваш код плох: вы постоянно выделяете память, которая никогда не освобождается.