memcpy() 随机崩溃
我在我的应用程序中使用 memcpy 。 memcpy 随机崩溃,下面是我在 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 );
其中:
- dep 是一个结构
- EntryRec 是一个字符指针
- adp 是一个结构
- data 在这种情况下不是
NULL
有谁遇到过这个问题并且可以帮助我吗?
我尝试过调试程序, 然后我收到以下错误 Prog.exe(MSVCRTD.DLL) 中未处理的异常:0xC0000005:访问破坏
数据已传递给该程序,这是 void*
更多信息:
我已尝试调试代码适配器在该函数存在于 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=“”(未初始化) 我= 2147483598
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
从反汇编代码看来,源指针不在您的地址空间中。
rep movsb 从 ds:si 复制到 es:di。这 ??表示无法读取 ds:si 处的内存。
From the disassembled code it appears that the source pointer is not in your address space.
rep movsb copies from ds:si to es:di. The ?? indicates that the memory at ds:si could not be read.
(char *)dep + (int)sizeof(EntryRec) + (int)adp->fileHdr.keySize
指向的数据是否始终至少为dataSize
长?我遇到过类似的崩溃,其中可变长度字符串后来被视为用字符串固定。
例如,
其中
fixedLength
大于10
。显然,它们具有不同的功能,因此没有注意到长度问题。大多数情况下,这是可行的,dest
将包含“一些字符串”,并且在null之后将是随机垃圾。在这种情况下,如果您将 dest 视为以 null 结尾的字符串,您将永远不会注意到,因为您在 null 之后看不到垃圾。但是,如果
ptr
分配在内存页的末尾,则只能读取到已分配内存的末尾,而无法进一步读取。一旦您阅读完页面末尾,操作系统就会正确地使您的程序崩溃。Is the data pointed to by
(char *)dep + (int)sizeof(EntryRec) + (int)adp->fileHdr.keySize
always at leastdataSize
long?I have come across similar crashes where variable length strings are later treated like fixed with strings.
eg
Where
fixedLength
is greater than10
. Obviously these were in different functions so the length issue was not noticed. Most of the time this will work,dest
will contain "some string" and after the null will be random garbage. In this case if you treat dest as a null terminated string you will never notice, as you don't see the garbage after the null.However if
ptr
is allocated at the end of a page of memory, you can only read to the end of the allocated memory and no further. As soon as you read past the end of the page the operating system will rightly crash your program.看起来您已经超出了缓冲区的末尾并产生了访问冲突。
编辑:仍然没有足够的信息。如果不了解更多有关您尝试复制到的缓冲区如何分配是否有足够的空间(我怀疑它没有)以及 dataSize 是否有效的信息,我们就无法发现错误。
It looks like you've run over the end of a buffer and generated an access violation.
Edit: There still is not enough information. We cannot spot a bug without knowing much more about how the buffer you are trying to copy to is allocated whether it has enough space (I suspect it does not) and whether dataSize is valid.
如果 memcpy 崩溃,通常的原因是您传递了非法参数。
请注意,使用 memcpy 源和目标可能不会重叠。
在这种情况下使用 memmove。
If memcpy crashes the usual reason is, that you passed illegal arguments.
Note that with memcpy source and destination may not overlap.
In such a case use memmove.
从您的代码“memcpy((char *)dep + (int)sizeof(EntryRec) + (int)adp->fileHdr.keySize, data, dataSize)”和调试信息来看,“data”看起来像一个局部变量(堆栈变量),您可以执行“data = malloc(DATA_SIZE)”而不是“char data[DATA_SIZE]”等;否则,在您当前的代码行,“数据”已经弹出,因此可能会随机导致内存访问错误。
from your code "memcpy((char *)dep + (int)sizeof(EntryRec) + (int)adp->fileHdr.keySize, data, dataSize)" and the debug infomation, the "data" looks like a local variable (on-stack variable), you'd do "data = malloc(DATA_SIZE)" instead of "char data[DATA_SIZE]" etc; otherwise, at your current code line, the "data" was popped already, so may cause memory accessing fault randomly.
我建议使用 memmove 因为它可以处理重叠的字符串,在这种情况下使用 memcpy 时结果是不可预测的。
I'd suggest using memmove as this handles overlapping strings, when using memcpy in this situation the result is unpredictable.
有两种非常可能的解释:
memcpy
——这种情况的行为是未定义的。如果您需要处理重叠地址的能力,std::memmove< /code>
是“等效”工具。
memcpy
在程序无法访问的内存中进行复制。从您显示的代码来看,(2)似乎是更可能的情况。由于您能够调试源代码,因此请尝试在
memcpy
发生之前设置断点,并验证memcpy
的参数是否全部匹配(即source + num 或
source > dest + num
)。There are two very likely explanations:
memcpy
across overlapping addresses -- the behavior of this situation is undefined. If you require the ability to handle overlapping addresses,std::memmove
is the "equivalent" tool.memcpy
to copy to/from memory that is inaccessible to your program.From the code you've shown, it looks like (2) is the more likely scenario. Since you are able to debug the source, try setting a breakpoint before the
memcpy
occurs, and verify that the arguments tomemcpy
all match up (i.e.source + num < dest
orsource > dest + num
).