我在我的应用程序中使用memcpy。 memcpy randomely崩溃,下面是Dr.Watson文件中的日志。
100181b5 8bd1 mov edx,ecx
100181b7 c1e902 shr ecx,0x2
100181ba 8d7c030c lea edi,[ebx+eax+0xc]
100181be f3a5 rep movsd
100181c0 8bca mov ecx,edx
100181c2 83e103 and ecx,0x3
FAULT ->100181c5 f3a4 rep movsb ds:02a3b000=?? es:01b14e64=00
100181c7 ff1508450210 call dword ptr [Debug (10024508)]
100181cd 83c424 add esp,0x24
100181d0 6854580210 push 0x10025854
100181d5 ff1508450210 call dword ptr [Debug (10024508)]
100181db 83c404 add esp,0x4
以下是代码
memcpy((char *)dep + (int)sizeof(EntryRec) + (int)adp->fileHdr.keySize, data, dataSize );
其中:
NULL
有没有人遇到过这个问题,可以帮助我?
我试过调试编程, 然后我得到以下错误 Prog.exe中未处理的异常(MSVCRTD.DLL):0xC0000005:访问声音
数据传递给该程序的参数,这是无效的*
更多信息:
我试过调试代码适配器在以下区域崩溃这个函数出现在OUTPUT.c中(我认为这是一个库函数)
#else /* _UNICODE */
if (flags & (FL_LONG|FL_WIDECHAR)) {
if (text.wz == NULL) /* NULL passed, use special string */
text.wz = __wnullstring;
bufferiswide = 1;
pwch = text.wz;
while ( i-- && *pwch )
++pwch;
textlen = pwch - text.wz;
/* textlen now contains length in wide chars */
} else {
if (text.sz == NULL) /* NULL passed, use special string */
text.sz = __nullstring;
p = text.sz;
while (i-- && *p) //Crash points here
++p;
textlen = p - text.sz; /* length of the string */
}
变量的值: p =“”(未初始化) i = 2147483598
答案 0 :(得分:17)
有两种非常可能的解释:
memcpy
- 此情况的行为未定义。如果您需要处理重叠地址的能力,std::memmove
是“等效”工具。memcpy
复制到程序无法访问的内存中。从您显示的代码中,看起来(2)更可能是场景。由于您可以调试源代码,请尝试在memcpy
发生之前设置断点,并验证memcpy
的参数是否都匹配(即source + num < dest
或source > dest + num
)
答案 1 :(得分:10)
从反汇编的代码中可以看出源指针不在您的地址空间中。 rep movsb副本从ds:si到es:di。 ?? ??表示无法读取ds:si处的内存。
答案 2 :(得分:1)
看起来你已经在缓冲区的末尾运行并产生了访问冲突。
编辑:仍然没有足够的信息。我们无法在不了解您尝试复制的缓冲区如何分配是否有足够的空间(我怀疑它没有)以及dataSize是否有效的情况下发现错误。
答案 3 :(得分:1)
如果memcpy崩溃,通常的原因是,你通过了非法论据。
请注意,memcpy源和目标可能不会重叠。
在这种情况下使用memmove。
答案 4 :(得分:1)
从您的代码“memcpy((char *)dep +(int)sizeof(EntryRec)+(int)adp-&gt; fileHdr.keySize,data,dataSize)”和调试信息,“数据”看起来像一个局部变量(on-stack变量),你要做“data = malloc(DATA_SIZE)”而不是“char data [DATA_SIZE]”等;否则,在您当前的代码行中,“数据”已经弹出,因此可能导致内存随机访问故障。
答案 5 :(得分:1)
(char *)dep + (int)sizeof(EntryRec) + (int)adp->fileHdr.keySize
指向的数据总是至少dataSize
长吗?
我遇到过类似的崩溃,其中可变长度字符串后来被视为固定字符串。
例如
char * ptr = strdup("some string");
// ...
memcpy(ptr, dest, fixedLength);
fixedLength
大于10
的位置。显然这些功能不同,因此没有注意到长度问题。大多数情况下这将起作用,dest
将包含“一些字符串”,并且在null之后将是随机垃圾。在这种情况下,如果您将dest视为空终止字符串,您将永远不会注意到,因为您在null之后没有看到垃圾。
但是,如果在内存页面的末尾分配ptr
,则只能读取已分配内存的末尾而不再进一步。一旦您阅读了页面末尾,操作系统就会正确地崩溃您的程序。
答案 6 :(得分:0)
我建议使用memmove,因为它处理重叠字符串,在这种情况下使用memcpy时结果是不可预测的。