为什么在将 LPBYTE 复制到 LPTSTR(剪贴板)期间使用 memcpy 抛出异常?
我有一个 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
我并不是说,这是你问题的原因,但它可能是或可能是将来其他问题的原因。
如果您像这样分配内存
这是对已分配内存块之外的访问:
分配的内存大小为
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
This is an access outside of the allocated chunk of memory:
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. Ifsizeof(TCHAR)
is 1, the last read byte islpByte[lSize]
and ifsizeof(TCHAR)
is more that 1, bytes pastlpByte[lSize]
are also read or at least attempted to be.我不确定是什么导致您的代码出现问题,但是以下代码可以工作,并且所有内容都锁定/复制,很好(请注意,您的剪贴板操作可以轻松注释掉,并且不会影响问题的根源):
您可以尝试在异常发生之前在代码中设置断点(实际上可能有不同的原因)。
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):
You could try setting breakpoints in your code right before the exception happens (it could actually have different reasons).
GlobalAlloc 或 GlobalLock 有效吗?输入一些错误检查代码并查看,两者都应该返回非 NULL 值。
Do GlobalAlloc or GlobalLock work? Put some error checking code in and see, both should return non-NULL values.
_wfopen
是fopen
的宽字符版本 - 您应该传递 L"...",而不是 TCHAR。 TCHAR 版本是_tfopen
(将归结为fopen
或_wfopen
之一) - 请参阅:http://msdn.microsoft.com/en-us/library/yeby3zcb%28VS.80 %29.aspx如果这是 C,则实际上不需要转换 malloc 的结果。就我个人而言,MS
LP*
类型给我留下了不好的印象 - 我觉得匈牙利语掩盖了精通 C 语言的人的代码可读性。因此,我更喜欢BYTE *
优于LPBYTE
,但它不会创建或破坏代码。检查返回值。
正如其他人提到的,此内存访问超出了数组范围。
lpByte
GetLastError()
...成功了吗?接下来,
虽然我更喜欢非 LP 的东西,但也许选择一个? (也许可以进行转换
LPTSTR
?)同样,最终这并不重要。 (这可能属于“它是一个 malloc,也不需要强制转换”。)正如其他人提到的,这个 memcpy 也访问无效内存。具体来说,
lpByte
的长度为lSize
,但您在执行此操作时还加上了额外的sizeof(TCHAR)
。_wfopen
is the wide character version offopen
- you should be passing it L"...", not TCHARs. The TCHAR version is_tfopen
(which will boil down to one offopen
or_wfopen
) - See: http://msdn.microsoft.com/en-us/library/yeby3zcb%28VS.80%29.aspxIf 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 preferBYTE *
overLPBYTE
, but it's not going to make or break code.Check the return value.
As others mentioned, this memory access is out of the array bounds.
lpByte
GetLastError()
... on success?Next,
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.)As others mentioned, this memcpy is also accessing invalid memory. Specifically,
lpByte
islSize
long, but you're doing that plus an extrasizeof(TCHAR)
.