memcpy()随机崩溃

时间:2009-10-15 11:19:17

标签: c++ memcpy

我在我的应用程序中使用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 ); 

其中:

  • dep是一个结构
  • EntryRec是一个字符指针
  • adp是一个结构
  • 在这种情况下,
  • 数据不是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

7 个答案:

答案 0 :(得分:17)

有两种非常可能的解释:

  1. 您在重叠地址中使用memcpy - 此情况的行为未定义。如果您需要处理重叠地址的能力,std::memmove是“等效”工具。
  2. 您正在使用memcpy复制到程序无法访问的内存中。
  3. 从您显示的代码中,看起来(2)更可能是场景。由于您可以调试源代码,请尝试在memcpy发生之前设置断点,并验证memcpy的参数是否都匹配(即source + num < destsource > 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时结果是不可预测的。