为什么在将 LPBYTE 复制到 LPTSTR(剪贴板)期间使用 memcpy 抛出异常?

发布于 2024-09-04 11:37:42 字数 759 浏览 9 评论 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)));

最后一个字符串就是抛出异常的地方。 多谢

I have a LPBYTE array (taken from file) and I need to copy it into LPTSRT (actually into the clipboard). The trouble is copying work but unstable, sometime an exception was thrown (not always) and I don't understand why. The code is:

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

The last string is the place where the exception is thrown.
Thanks a lot

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

氛圍 2024-09-11 11:37:42

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

如果您像这样分配内存

LPBYTE lpByte = (LPBYTE) malloc(lSize);  

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

lpByte[lSize] = 0;

分配的内存大小为lSize,并且包含&lpByte[0]形式的位置&lpByte[lSize - 1] 包括在内。

编辑:

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

I'm not saying, it's the cause of Your problems, but it may be or may be a cause of other problems in the future.

If You allocate memory like this

LPBYTE lpByte = (LPBYTE) malloc(lSize);  

This is an access outside of the allocated chunk of memory:

lpByte[lSize] = 0;

Allocated memory has size of lSize and it contains locations form &lpByte[0] to &lpByte[lSize - 1] inclusive.

EDIT:

As Hans noticed, memcpy also accesses the memory outside of the allocated block. If sizeof(TCHAR) is 1, the last read byte is lpByte[lSize] and if sizeof(TCHAR) is more that 1, bytes past lpByte[lSize] are also read or at least attempted to be.

世界等同你 2024-09-11 11:37:42

我不确定是什么导致您的代码出现问题,但是以下代码可以工作,并且所有内容都锁定/复制,很好(请注意,您的剪贴板操作可以轻松注释掉,并且不会影响问题的根源)

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

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

I am not sure about what causes problems in your code, but the following code works and everything is locked / copied fine (note that your clipboard operations could be easily commented out and have no impact on the problem's source):

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

You could try setting breakpoints in your code right before the exception happens (it could actually have different reasons).

时光是把杀猪刀 2024-09-11 11:37:42

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

Do GlobalAlloc or GlobalLock work? Put some error checking code in and see, both should return non-NULL values.

帅的被狗咬 2024-09-11 11:37:42

_wfopenfopen 的宽字符版本 - 您应该传递 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 的结果。就我个人而言,MS 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)

_wfopen is the wide character version of fopen - you should be passing it L"...", not TCHARs. The TCHAR version is _tfopen (which will boil down to one of fopen or _wfopen) - See: http://msdn.microsoft.com/en-us/library/yeby3zcb%28VS.80%29.aspx

LPBYTE lpByte = (LPBYTE) malloc(lSize);

If this is C, you don't really need to cast malloc's result. Personally, the MS LP* types leave a bad taste in my mouth - I feel the Hungarian obscures the readability of the code to someone well versed in... C. Thus, I prefer BYTE * over LPBYTE, but it's not going to make or break code.

fread(lpByte, 1, lSize, fConnect);

Check the return value.

lpByte[lSize] = 0;

As others mentioned, this memory access is out of the array bounds.

if (!openRes)
    return;
DWORD err = GetLastError();
  • You leak lpByte
  • You call GetLastError() ... on success?

Next,

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

While I prefer the non-LP stuff, perhaps choose one? (Maybe make the cast LPTSTR?) Again, it shouldn't matter in the end. (This might fall under a "It's a malloc, and doesn't need a cast" as well.)

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

As others mentioned, this memcpy is also accessing invalid memory. Specifically, lpByte is lSize long, but you're doing that plus an extra sizeof(TCHAR).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文