0

我有一个 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

4 回答 4

3

我不是说,这是你的问题的原因,但它可能是或可能是未来其他问题的原因。

如果你像这样分配内存

LPBYTE lpByte = (LPBYTE) malloc(lSize);  

这是分配的内存块之外的访问:

lpByte[lSize] = 0;

分配的内存大小为,lSize它包含包含在内的位置。&lpByte[0]&lpByte[lSize - 1]

编辑:

正如 Hans 所注意到的,memcpy它还访问了分配块之外的内存。如果sizeof(TCHAR)为 1,则最后读取的字节为lpByte[lSize],如果大于sizeof(TCHAR)1,则过去lpByte[lSize]的字节也被读取或至少尝试读取。

于 2010-06-05T00:50:02.967 回答
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);

您可以尝试在异常发生之前在代码中设置断点(实际上可能有不同的原因)。

于 2010-06-05T00:51:50.950 回答
0

GlobalAlloc 或 GlobalLock 是否有效?放入一些错误检查代码,看看,两者都应该返回非 NULL 值。

于 2010-06-05T00:42:58.503 回答
0

_wfopen是宽字符版本fopen- 你应该传递它 L"...",而不是 TCHARs。TCHAR 版本是_tfopen(归结为fopenor之一_wfopen) - 请参阅:http: //msdn.microsoft.com/en-us/library/yeby3zcb%28VS.80%29.aspx

LPBYTE lpByte = (LPBYTE) malloc(lSize);

如果这是 C,你真的不需要转换 malloc 的结果。就个人而言,MSLP*类型在我的嘴里留下了不好的味道——我觉得匈牙利语模糊了代码对精通... 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 也在访问无效内存。具体来说,lpBytelSize长,但你正在这样做加上一个额外的sizeof(TCHAR).

于 2010-06-08T05:53:41.417 回答