2010-06-05 3 views
0

파일에서 가져온 LPBYTE 배열이 있고 LPTSRT로 복사해야합니다 (사실 클립 보드에 복사해야합니다). 문제는 복사 작업이지만 불안정합니다. 언젠가 예외가 발생했습니다 (항상 그런 것은 아닙니다). 이유를 이해하지 못합니다. 코드는 다음과 같습니다.LPBYTE를 LPTSTR (클립 보드)로 복사하는 중 memcpy에서 예외가 발생하는 이유는 무엇입니까?

 FILE *fConnect = _wfopen(connectFilePath, _T("rb")); 
    if (!fConnect) 
    return; 
    fseek(fConnect, 0, SEEK_END); 
    lSize = ftell(fConnect); 
    rewind(fConnect); 

    LPBYTE lpByte = (LPBYTE) malloc(lSize); 
    fread(lpByte, 1, lSize, fConnect); 
    lpByte[lSize] = 0; 
    fclose(fConnect); 

    //Copy into clipboard 
    BOOL openRes = OpenClipboard(NULL); 
    if (!openRes) 
    return; 
    DWORD err = GetLastError(); 

    EmptyClipboard(); 
    HGLOBAL hText; 
    hText = GlobalAlloc(GMEM_MOVEABLE, (lSize+ sizeof(TCHAR))); 

    LPTSTR sMem = (TCHAR*)GlobalLock(hText); 
    memcpy(sMem, lpByte, (lSize + sizeof(TCHAR))); 

마지막 문자열은 예외가 발생하는 장소입니다. 고마워요

답변

0

GlobalAlloc 또는 GlobalLock이 작동합니까? 에러 체크 코드를 넣고 보아라. 양쪽 모두 NULL이 아닌 값을 리턴해야한다.

+0

예, 제대로 작동합니다. – mimic

3

나는 그것이 귀하의 문제의 원인이지만, 다른 문제의 원인이 될 수 있음을 의미하지는 않습니다.

LPBYTE lpByte = (LPBYTE) malloc(lSize); 

이 같은 메모리의 메모리가 할당 된 청크의 외부 액세스입니다 할당 할 경우이 위치를 &lpByte[0]&lpByte[lSize - 1]을에 형성 포함

lpByte[lSize] = 0; 

할당 된 메모리가 lSize의 크기를 가지고 있으며, 포함한.

EDIT :

로서 한스 memcpy 또한 할당 된 블록의 외부 메모리에 액세스 차렸다. sizeof(TCHAR)이 1이면 마지막 읽기 바이트는 lpByte[lSize]이고 sizeof(TCHAR)이 1 이상이면 lpByte[lSize] 바이트가 읽히거나 적어도 읽으려고 시도합니다.

+0

범위를 벗어났습니다. 심각한 문제가 발생했습니다. –

+0

예외가 무엇인지 알 수 있습니다. 코드는 800401fd입니다. 서버에 연결되어 있지 않은 개체가 있습니다. 하지만 나는 그것이 무엇을 의미하는지 전혀 모르겠다. – mimic

+2

memcpy()도 범위를 벗어났다. 아마도 2가 될 수도있다. –

1

난 당신의 코드에서 문제가 발생하지만, 다음 코드는 어떤 작품에 대해 확실하지 오전 모든 이 (클립 보드 작업이 쉽게 주석 처리 할 수 ​​있습니다 복사/잠겨하고 문제의 소스에 영향을 미치지 않는다) :

LPBYTE lpByte = (LPBYTE)malloc(512); 
    lpByte[0] = 'A'; 
    lpByte[1] = 'B'; 
    lpByte[2] = '0'; 

    // OpenClipboard(NULL); 
    // EmptyClipboard(); 

    HGLOBAL hText; 
    hText = GlobalAlloc(GMEM_MOVEABLE, 512); 

    LPTSTR sMem = (TCHAR*)GlobalLock(hText); 
    memcpy(sMem, lpByte, 512); 

당신은 바로 예외 전에 코드에 중단 점을 설정하려고 할 수 있습니다 (이것은 다른 이유가 실제로있을 수 있습니다) 발생합니다.

+0

Suer 나는 무엇을보아야할지 모르지만 ... 가장 불쾌한 것은 예외가 항상있는 것은 아니며 예외가 무엇인지 모른다. – mimic

0

_wfopen은 와이드 문자 버전 fopen입니다. TCHAR이 아닌 L "..."을 전달해야합니다. TCHAR 버전 (fopen 또는 _wfopen 중 하나로 귀결되는) _tfopen입니다 - 참조 : http://msdn.microsoft.com/en-us/library/yeby3zcb%28VS.80%29.aspx

LPBYTE lpByte = (LPBYTE) malloc(lSize); 

를이 C 인 경우, 당신은 정말의 malloc의 결과를 캐스팅 할 필요가 없습니다. 개인적으로 MS LP* 유형은 입안에 좋지 않은 맛을 남깁니다. 나는 헝가리 인이 ... C에 정통한 사람에게 코드의 가독성을 모호하게 느낍니다. 따라서 BYTE *LPBYTE 이상으로 선호하지만 만들거나 깨뜨리지 않을 것입니다. 암호.

fread(lpByte, 1, lSize, fConnect); 

반환 값을 확인하십시오.

lpByte[lSize] = 0; 

다른 언급처럼,이 메모리 액세스는 배열 범위를 벗어납니다.

if (!openRes) 
    return; 
DWORD err = GetLastError(); 
  • 당신은 성공에 ... 당신은 GetLastError() 전화
  • lpByte 누출? 나는 비 LP 물건을 선호하는 반면

다음,

LPTSTR sMem = (TCHAR*)GlobalLock(hText); 

, 아마도 하나를 선택? (어쩌면 캐스트를 LPTSTR으로 만드시겠습니까?) 다시 말하지만, 결국에는 중요하지 않습니다. (A뿐만 아니라 "이것은 malloc에, 그리고 깁스를 필요로하지 않는다"에서이 떨어질 수 있습니다.) 다른 사람이 언급 한 바와 같이,이 방어 적이기도 잘못된 메모리에 액세스하는

memcpy(sMem, lpByte, (lSize + sizeof(TCHAR))); 

. 구체적으로 lpByte은 길이가 lSize입니다.하지만 여기에 추가로 sizeof(TCHAR)을 더한 것입니다.