首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ Builder >

大侠救救小弟我,一个内存突然改变的有关问题,卡了小弟我很久

2012-03-22 
【求助】大侠救救我,一个内存突然改变的问题,卡了我很久 - C++ Builder / Windows SDK/API先贴代码:Russia.h

【求助】大侠救救我,一个内存突然改变的问题,卡了我很久 - C++ Builder / Windows SDK/API
先贴代码:
Russia.h:

C/C++ code
#define Lstru(x,y)  {SI=sizeof(POINTS)*4*4;\                                   POINTS Lstru[4][4]={x,y,x+1,y,x,y-1,x,y-2,\                                                               x,y,x,y-1,x+1,y-1,x+2,y-1,\                                                               x,y-2,x+1,y-2,x+1,y-1,x+1,y,\                                                               x,y,x+1,y,x+2,y,x+2,y-1};\                                   now=Lstru;\                                  }#define Tstru(x,y)  {\                                  SI=sizeof(POINTS)*4*4;\                                  POINTS Tstru[4][4]={x,y,x+1,y,x+2,y,x+1,y-1,\                                                               x,y,x,y-1,x,y-2,x-1,y-1,\                                                               x+1,y,x,y-1,x+1,y-1,x+2,y-1,\                                                               x,y-1,x+1,y,x+1,y-1,x+1,y-2};\                                                               now=Tstru;}#define Zstru(x,y)  {\                                  SI=sizeof(POINTS)*2*4;\                                  POINTS Zstru[2][4]={x,y,x+1,y,x+1,y-1,x+2,y-1,\                                                               x,y-1,x,y-2,x+1,y,x+1,y-1};\                                                               now=Zstru;}#define Istru(x,y)   {\                                  SI=sizeof(POINTS)*2*4;\                                   POINTS Istru[2][4]={x,y,x+1,y,x+2,y,x+3,y,\                                                               x,y,x,y-1,x,y-2,x,y-3};\                                                               now=Istru;}#define Hstru(x,y) {SI=sizeof(POINTS)*4;\                                   POINTS Hstru[4]={x,y,x+1,y,x,y-1,x+1,y-1};\                                                               now=Hstru;}


Russia.cpp:
C/C++ code
 

#include <windows.h>
#include"Russia.h"
#define RUSSIA TEXT("Russia")
#define CELL 20
LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);
int Data[25][15]={0};
RECT rect;
static void *now=NULL;
POINTS *tem=NULL;
POINTS *tru=NULL;
int SI,i;
POINTS * IsOK(int dr);
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,
                  PSTR iCmdLine,int iShowCmd)
{
    HWND hwnd;
    MSG msg;
    WNDCLASS wndclass;

    wndclass.style=CS_HREDRAW|CS_VREDRAW;
    wndclass.cbClsExtra=0;
    wndclass.cbWndExtra=0;
    wndclass.lpfnWndProc=WndProc;
    wndclass.hInstance=hInstance;
    wndclass.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);
    wndclass.hCursor=LoadCursor(NULL,IDC_ARROW);
    wndclass.hIcon=LoadIcon(NULL,IDI_INFORMATION);
    wndclass.lpszMenuName=NULL;
    wndclass.lpszClassName=RUSSIA;

    if(!RegisterClass(&wndclass))
        return 0;
    if(!(hwnd=CreateWindow(RUSSIA,TEXT("Russia"),
        WS_OVERLAPPED,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,
        NULL,NULL,hInstance,NULL)))
        return 0;
    ShowWindow(hwnd,iShowCmd);
    UpdateWindow(hwnd);
    while(GetMessage(&msg,NULL,0,0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }


    return msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
{
    PAINTSTRUCT ps;
    HDC hdc;

    switch(message)
    {
    case WM_CREATE:
        i=rand()%4;
        if(i==0)
            Lstru(7,0)
        else if(i==1)  Tstru(7,0)
        else if(i==2)  Zstru(7,0)
        else if(i==3)  Istru(7,0)
        else Hstru(7,0)
        tru=(POINTS *)now;
        SetTimer(hwnd,1,500,NULL);
        return 0;
    case WM_TIMER:
        IsOK(0);
        InvalidateRect(hwnd,NULL,true);
        return 0;
    case WM_PAINT:
        hdc=BeginPaint(hwnd,&ps);
        for(int w=0;w <=300;w+=CELL)
        {
            MoveToEx(hdc,w,0,NULL);
            LineTo(hdc,w,500);
        }
        for(int h=0;h <=500;h+=CELL)
        {
            MoveToEx(hdc,0,h,NULL);
            LineTo(hdc,300,h);
        }
        tem=tru;
        for (i=0;i <4;i++)
        {
          rect.left=(tem->x)*CELL;
          rect.bottom=(tem->y)*CELL;
          rect.right=(tem->x)*(CELL+1);
          rect.top=(tem->y)*(CELL+1);
          FillRect(hdc,&rect,(HBRUSH)BLACK_BRUSH);
          tem++;
        }

        for(i=0;i <15;i++)
            for(int j=0;j <25;j++)
            {
                if(Data[i][j]==1)
                {
                POINTS p;
                p.x=i*CELL;
                p.y=j*CELL;
                rect.left=p.x;rect.bottom=p.y;
                rect.right=p.x+CELL;rect.top=p.y+CELL;
                FillRect(hdc,&rect,(HBRUSH)GRAY_BRUSH);
                }
            }
        EndPaint(hwnd,&ps);
        return 0;       
    case WM_DESTROY:
        tru=NULL;
        tem=NULL;
        free(now);
        now=NULL;
        PostQuitMessage(0);
        return 0;
    }
    return DefWindowProc(hwnd,message,wParam,lParam);
}

POINTS * IsOK(int dr)
{
    if(dr==0)//will down
    {
        tem=tru;
        for(int i=0;i <4;i++)
        {


            if(tem->x <14&&tem->y>=0&&tem->y <24&&tem->y>=0)
            {
            if (Data[tem->x][tem->y+1]==1||(tem->y+1)>24)
                return ((POINTS *)now);
            tem++;}
        }
        tem=(POINTS *)now;
        for(int i=0;i <SI;)
        {
            (tem->y)++;
            tem++;
            i+=2;
        }
        return (tru);
    }
    else if(dr==1)//will left
    {
        tem=tru;
        for(int i=0;i <4;i++)
        {
            if(tem->x <14&&tem->y>=0&&tem->y <24&&tem->y>=0)
            {
            if (Data[tem->x-1][tem->y]==1||(tem->x-1) <0)
                return ((POINTS *)now);
            tem++;}
        }
        tem=(POINTS *)now;
        for(int i=0;i <SI;)
        {
            (tem->x)--;
            tem++;
            i+=2;
        }
        return (tru);
    }
    else
    {//will right
        tem=tru;
        for(int i=0;i <4;i++)
        {if(tem->x <14&&tem->y>=0&&tem->y <24&&tem->y>=0)
            {if (Data[tem->x+1][tem->y]==1||(tem->x++)>14)
                return ((POINTS *)now);
            tem++;
        }
        }
        tem=(POINTS *)now;
        for(int i=0;i <SI;)
        {
            (tem->x)++;
            tem++;
            i+=2;
        }
    }
}
//for down ,left or right OK?



这是我自己写的一个俄罗斯方块,没有完成,因为没有参考别人的例子,写法有点非主流,大家可以不必关注。

//大侠们注意,没有必要去看我所有代码,全贴出来,只是想让大侠们能帮忙用VS调试一下而已,问题的只是其中的一个内存改变的问题//

劳烦大侠把代码复制进VC运行看看,我有试过断点调试,发现now指针在WM_CREATE时,指向的内存区域数值为{x=7,y=0}
但是当运行到WM_PAINT时,now指针所指向的内存区域数值却变成了{x=19788,y=62},从而导致,Data当中的数值溢出,请大侠帮我看看到底是怎么回事…………


…………大伙万万不要不理我啊……


[解决办法]
now指向局部变量?
[解决办法]
#define Lstru(x,y) {SI=sizeof(POINTS)*4*4;\
POINTS Lstru[4][4]={x,y,x+1,y,x,y-1,x,y-2,\
x,y,x,y-1,x+1,y-1,x+2,y-1,\
x,y-2,x+1,y-2,x+1,y-1,x+1,y,\
x,y,x+1,y,x+2,y,x+2,y-1};\


now=Lstru;\
}
从这个宏看,now指向局部变量,这个局部变量的生命期很短,出了这全宏,其生命期也就结束。这上宏也就是没起到实际作用。局部变量不是等到return 0生命期才结束,而是只存活在定义它的{}间。

你可以用new将变量放在堆中,这样其生命期会一直到你delete它时,才结束。
[解决办法]

探讨

谢谢,不过我想再请教,您也看见了,宏里面有一堆根据X,Y来计算生成的数据,我就是想能够在程序中,随时能够马上输入想X,Y的值之后,就能够得到这存储有一连串数据的数组,并且在后面的程序中能够随时调用这个数组。

先前我只想到#define这种定义比较方便,怎知出现这种局部变量问题。

敢问大侠们,有什么比较好的解决方案,能随时自动根据X,Y生成数组呢

热点排行