我有一个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)));
最后一个字符串是抛出异常的地方。 非常感谢
答案 0 :(得分: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]
字节。
答案 1 :(得分: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);
您可以尝试在异常发生之前在代码中设置断点(实际上可能有不同的原因)。
答案 2 :(得分:0)
GlobalAlloc或GlobalLock有效吗?将一些错误检查代码放入并查看,两者都应返回非NULL值。
答案 3 :(得分:0)
_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的结果。就个人而言,MS LP*
类型在我的口中留下了不好的味道 - 我觉得匈牙利人将代码的可读性模仿给精通...的人。因此,我更喜欢BYTE *
而不是LPBYTE
1}},但它不会破坏代码。
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)
,但您正在执行此操作并加{{1}}。