Почему исключение выдается при использовании memcpy при копировании LPBYTE в LPTSTR (буфер обмена)?

У меня есть массив LPBYTE (взятый из файла), и мне нужно скопировать его в LPTSRT (фактически в буфер обмена). Проблема в том, что работа копируется, но нестабильно, иногда выдается исключение (не всегда), и я не понимаю, почему. Код является:

     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)));

Последняя строка - это место, где выдается исключение. большое спасибо

4 ответа

Я не говорю, что это причина Ваших проблем, но это может быть или может быть причиной других проблем в будущем.

Если вы выделите память, как это

LPBYTE lpByte = (LPBYTE) malloc(lSize);  

Это доступ за пределами выделенного фрагмента памяти:

lpByte[lSize] = 0;

Выделенная память имеет размер lSize и он содержит форму местоположения &lpByte[0] в &lpByte[lSize - 1] включительно.

РЕДАКТИРОВАТЬ:

Как заметил Ганс, memcpy также обращается к памяти за пределами выделенного блока. Если sizeof(TCHAR) 1, последний прочитанный байт lpByte[lSize] и если sizeof(TCHAR) больше 1, байт прошло lpByte[lSize] также читаются или, по крайней мере, пытались быть.

Я не уверен в том, что вызывает проблемы в вашем коде, но следующий код работает, и все отлично блокируется / копируется (обратите внимание, что ваши операции с буфером обмена могут быть легко закомментированы и не влияют на источник проблемы):

   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);

Вы можете попытаться установить точки останова в своем коде прямо перед тем, как произойдет исключение (на самом деле это может иметь разные причины)

Работают ли GlobalAlloc или GlobalLock? Вставьте код проверки ошибок и посмотрите, оба должны возвращать ненулевые значения.

_wfopen это широкоформатная версия fopen - вы должны передавать это L"...", а не TCHAR. Версия TCHAR _tfopen (который будет сводиться к одному из fopen или же _wfopen) - См.: http://msdn.microsoft.com/en-us/library/yeby3zcb%28VS.80%29.aspx

LPBYTE lpByte = (LPBYTE) malloc(lSize);

Если это C, вам не нужно приводить результат malloc. Лично МС LP* типы оставляют во рту дурной вкус - я чувствую, что венгерский язык скрывает читабельность кода кому-то, кто хорошо разбирается в... C. Таким образом, я предпочитаю BYTE * над LPBYTE, но это не собирается делать или нарушать код.

fread(lpByte, 1, lSize, fConnect);

Проверьте возвращаемое значение.

lpByte[lSize] = 0;

Как уже упоминалось, этот доступ к памяти находится за пределами массива.

if (!openRes)
    return;
DWORD err = GetLastError();
  • Ты утечка lpByte
  • Ты звонишь GetLastError()... в случае успеха?

Следующий,

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

Хотя я предпочитаю не-LP материал, возможно, выбрать один? (Может быть, сделать бросок LPTSTR?) Опять же, это не должно иметь значения в конце концов. (Это также может относиться к категории "Это - malloc, и ему не нужен бросок".)

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

Как уже упоминалось, этот memcpy также обращается к недействительной памяти. В частности, lpByte является lSize долго, но вы делаете это плюс дополнительный sizeof(TCHAR),

Другие вопросы по тегам