VC6.0 memcpy()函数为什么报错啊

时间:2021-06-12 10:34:14
DWORD WINAPI ThFunc(LPVOID v)
{

while(1)
{
DWORD HeroNum=0;
BYTE GameState=0;
memcpy(&HeroNum,(LPCVOID)(w3.GetHeroNumAddr()),4);//这句报错,报错信息如下
memcpy(&GameState,(LPCVOID)(w3.GetGameStateAddr()),1);//这句报错,报错信息如下
if((GameState==0xc4)&&(HeroNum>0))
{
pSleep(100);
DWORD TempCalc=*(DWORD*)(w3.GameAddr+0xacd06c);//这句报错,报错信息如下
if (TempCalc==0)
{
printf("1111=0\n");
continue;
}
TempCalc+=0x17c;
TempCalc=*(DWORD*)TempCalc;    //这句报错,报错信息如下
if (TempCalc==0)
{
printf("222=0\n");
continue;
}
TempCalc=*(DWORD*)TempCalc;  //这句报错,报错信息如下
if (TempCalc==0)
{
printf("333=0\n");
continue;
}
MiniMapPixel=(DWORD*)TempCalc;
printf("游戏开始了\n");


}
}
return 1;
}

//报错信息:unhandled exception in xx.exe:0x0000005:access violation!!
//报错信息:unhandled exception in xx.exe:0x0000005:access violation!!
//报错信息:unhandled exception in xx.exe:0x0000005:access violation!!

帮帮忙啊!!大神们!!在线等答案,急~~~~~~~~

13 个解决方案

#1


非法访问,你的目标地址没问题,那不就是你的源地址的问题了呗,w3.GetHeroNumAddr()这是啥玩意

#2


引用 1 楼 spirit008 的回复:
非法访问,你的目标地址没问题,那不就是你的源地址的问题了呗,w3.GetHeroNumAddr()这是啥玩意

这个没问题的,我跟程序看了,有值的。。返回1个dword类型的值

#3


你可以直接:
DWORD HeroNum = w3.GetHeroNumAddr();

#4


DWORD HeroNum=0;
BYTE GameState=0;
memcpy(&HeroNum,(LPCVOID)(w3.GetHeroNumAddr()),4);//这句报错,报错信息如下

直接:
DWORD HeroNum =(DWORD ) *w3.GetHeroNumAddr();

#5


void *memcpy(void *dest, const void *src, size_t n);
确认传的三个参数都是有效的,而且前面2个地址不为空,不覆盖!
如果有可能覆盖的话考虑用memmove函数

#6


引用 4 楼 worldy 的回复:
DWORD HeroNum=0;
BYTE GameState=0;
memcpy(&HeroNum,(LPCVOID)(w3.GetHeroNumAddr()),4);//这句报错,报错信息如下

直接:
DWORD HeroNum =(DWORD ) *w3.GetHeroNumAddr();



那我要截取长度4怎么办呢

#7


DWORD 不就是4的长度么?难到w3.GetHeroNumAddr() 返回的是数组的首地址?

#8


引用 7 楼 cmztestat 的回复:
DWORD 不就是4的长度么?难到w3.GetHeroNumAddr() 返回的是数组的首地址?


是的哦,我试试看。。。谢谢啊,那长度为1的呢?

#9


引用 4 楼 worldy 的回复:
DWORD HeroNum=0;
BYTE GameState=0;
memcpy(&HeroNum,(LPCVOID)(w3.GetHeroNumAddr()),4);//这句报错,报错信息如下

直接:
DWORD HeroNum =(DWORD ) *w3.GetHeroNumAddr();

DWORD HeroNum = *(DWORD *) w3.GetHeroNumAddr();
这么写都报错,报同样的错,至于你写的这个不对,编译都通过不了,意思应该是把w3.GetHeroNumAddr()数值对应的地址的值取出来给HeroNum,可是这么写为什么会报错呢???

#10


引用 7 楼 cmztestat 的回复:
DWORD 不就是4的长度么?难到w3.GetHeroNumAddr() 返回的是数组的首地址?

w3.GetHeroNumAddr() 返回的就是一个DWORD值,我确定,我觉得应该是HeroNum内存分配问题。。。

#11


如果GetHeroNumAddr返回的是地址,DWORD HeroNum =(DWORD ) *w3.GetHeroNumAddr();应该是没有错的,但或许该返回返回的不是地址,或者其返回地址之前必须先调用别的函数分配地址,你得看相关文档

#12


引用 11 楼 worldy 的回复:
如果GetHeroNumAddr返回的是地址,DWORD HeroNum =(DWORD ) *w3.GetHeroNumAddr();应该是没有错的,但或许该返回返回的不是地址,或者其返回地址之前必须先调用别的函数分配地址,你得看相关文档

但是同样的代码在dll中完全正确,搞不懂。。。

#13


崩溃的时候在弹出的对话框按相应按钮进入调试,按Alt+7键查看Call Stack里面从上到下列出的对应从里层到外层的函数调用历史。双击某一行可将光标定位到此次调用的源代码或汇编指令处。

判断是否越界访问,可以在数组的最后一个元素之后对应的地址处设置数据读写断点。如果该地址对应其它变量干扰判断,可将数组多声明一个元素,并设置数据读写断点在该多出元素对应的地址上。
#include <time.h>
#include <stdlib.h>
#include <windows.h>
int main() {
    int a,b[11];//本来是b[10],为判断哪句越界,故意声明为b[11]

    srand((unsigned int)time(NULL));//按两次F11,等黄色右箭头指向本行时,调试、新建断点、新建数据断点,地址:&b[10],字节计数:4,确定。
    while (1) {//按F5,会停在下面某句,此时a的值为10,b[10]已经被修改为对应0..4之一。
        b[(a=rand()%11)]=0;
        Sleep(100);
        b[(a=rand()%11)]=1;
        Sleep(100);
        b[(a=rand()%11)]=2;
        Sleep(100);
        b[(a=rand()%11)]=3;
        Sleep(100);
        b[(a=rand()%11)]=4;
        Sleep(100);
    }
    return 0;
}

#1


非法访问,你的目标地址没问题,那不就是你的源地址的问题了呗,w3.GetHeroNumAddr()这是啥玩意

#2


引用 1 楼 spirit008 的回复:
非法访问,你的目标地址没问题,那不就是你的源地址的问题了呗,w3.GetHeroNumAddr()这是啥玩意

这个没问题的,我跟程序看了,有值的。。返回1个dword类型的值

#3


你可以直接:
DWORD HeroNum = w3.GetHeroNumAddr();

#4


DWORD HeroNum=0;
BYTE GameState=0;
memcpy(&HeroNum,(LPCVOID)(w3.GetHeroNumAddr()),4);//这句报错,报错信息如下

直接:
DWORD HeroNum =(DWORD ) *w3.GetHeroNumAddr();

#5


void *memcpy(void *dest, const void *src, size_t n);
确认传的三个参数都是有效的,而且前面2个地址不为空,不覆盖!
如果有可能覆盖的话考虑用memmove函数

#6


引用 4 楼 worldy 的回复:
DWORD HeroNum=0;
BYTE GameState=0;
memcpy(&HeroNum,(LPCVOID)(w3.GetHeroNumAddr()),4);//这句报错,报错信息如下

直接:
DWORD HeroNum =(DWORD ) *w3.GetHeroNumAddr();



那我要截取长度4怎么办呢

#7


DWORD 不就是4的长度么?难到w3.GetHeroNumAddr() 返回的是数组的首地址?

#8


引用 7 楼 cmztestat 的回复:
DWORD 不就是4的长度么?难到w3.GetHeroNumAddr() 返回的是数组的首地址?


是的哦,我试试看。。。谢谢啊,那长度为1的呢?

#9


引用 4 楼 worldy 的回复:
DWORD HeroNum=0;
BYTE GameState=0;
memcpy(&HeroNum,(LPCVOID)(w3.GetHeroNumAddr()),4);//这句报错,报错信息如下

直接:
DWORD HeroNum =(DWORD ) *w3.GetHeroNumAddr();

DWORD HeroNum = *(DWORD *) w3.GetHeroNumAddr();
这么写都报错,报同样的错,至于你写的这个不对,编译都通过不了,意思应该是把w3.GetHeroNumAddr()数值对应的地址的值取出来给HeroNum,可是这么写为什么会报错呢???

#10


引用 7 楼 cmztestat 的回复:
DWORD 不就是4的长度么?难到w3.GetHeroNumAddr() 返回的是数组的首地址?

w3.GetHeroNumAddr() 返回的就是一个DWORD值,我确定,我觉得应该是HeroNum内存分配问题。。。

#11


如果GetHeroNumAddr返回的是地址,DWORD HeroNum =(DWORD ) *w3.GetHeroNumAddr();应该是没有错的,但或许该返回返回的不是地址,或者其返回地址之前必须先调用别的函数分配地址,你得看相关文档

#12


引用 11 楼 worldy 的回复:
如果GetHeroNumAddr返回的是地址,DWORD HeroNum =(DWORD ) *w3.GetHeroNumAddr();应该是没有错的,但或许该返回返回的不是地址,或者其返回地址之前必须先调用别的函数分配地址,你得看相关文档

但是同样的代码在dll中完全正确,搞不懂。。。

#13


崩溃的时候在弹出的对话框按相应按钮进入调试,按Alt+7键查看Call Stack里面从上到下列出的对应从里层到外层的函数调用历史。双击某一行可将光标定位到此次调用的源代码或汇编指令处。

判断是否越界访问,可以在数组的最后一个元素之后对应的地址处设置数据读写断点。如果该地址对应其它变量干扰判断,可将数组多声明一个元素,并设置数据读写断点在该多出元素对应的地址上。
#include <time.h>
#include <stdlib.h>
#include <windows.h>
int main() {
    int a,b[11];//本来是b[10],为判断哪句越界,故意声明为b[11]

    srand((unsigned int)time(NULL));//按两次F11,等黄色右箭头指向本行时,调试、新建断点、新建数据断点,地址:&b[10],字节计数:4,确定。
    while (1) {//按F5,会停在下面某句,此时a的值为10,b[10]已经被修改为对应0..4之一。
        b[(a=rand()%11)]=0;
        Sleep(100);
        b[(a=rand()%11)]=1;
        Sleep(100);
        b[(a=rand()%11)]=2;
        Sleep(100);
        b[(a=rand()%11)]=3;
        Sleep(100);
        b[(a=rand()%11)]=4;
        Sleep(100);
    }
    return 0;
}