很奇怪的一个非法内存访问

时间:2020-12-25 19:23:46
LRESULT AttrListProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
static HDC hdc;
static PAINTSTRUCT ps;
static ALITEM *item;
static LPTSTR cls;
static ALCLASS *thecls;
static AttrListStruct *als;

als = (AttrListStruct*)GetWindowLong( hWnd, 0 );
         switch( uMsg )
{
          ...
           case WM_CREATE:
als = new AttrListStruct;
als->Selection = 0;
als->hwndEdit = CreateWindow("edit", "", WS_CHILD, 
0, 0, 0, 0, 
hWnd, (HMENU)EDITCTRL, 
NULL, 0);//在这里产生非法内存访问,而上面一句正常.

调试发现,在执行到als->hwndEdit时,als的值突然变为0,这是一个单线程程序.并且如果als不是static的,就不会有非法内存访问的问题.

10 个解决方案

#1


越界了?

#2


new的时候 是否成功?
AttrListStruct 是否太大? 

非法内存访问, 调试时看汇编代码到底是访问了哪个地址?

#3


我上面应该说清楚了吧.

当执行到als->Selection = 0;的时候,指针是指向一个合法的地址的,而且这句执行正常
然后执行到als->hwndEdit = CreateWindow(...)这句的时候,als突然变成了0.

#4


非静态,那就确定是CreateWindow这个函数越界了,你看看参数。
将栈上的内容给替换掉了。

#5


这个是系统API,越界的可能性不大吧.而且即使越界,也不可能影响到静态存储区.

#6


你不是这样说的么?
并且如果als不是static的,就不会有非法内存访问的问题.


这个是系统API,越界的可能性不大吧.而且即使越界,也不可能影响到静态存储区.
===============================
怎么不可能
char sz[16]
GetWindowTextA( , sz , 256);假如窗口标题大小超过16,会不会越界?

#7


我觉得问题在于
als = (AttrListStruct*)GetWindowLong( hWnd, 0 );
当程序调用了CreateWindow的时候,这时主窗口创建了一个Edit.
这个Edit是主窗口得子窗口,那么应该会产生一些消息.
所以CreateWindow得同时,或则CreateWindow之后,AttrListProc收到了一个建立子窗口得消息.
而在处理这个消息得时候.als = (AttrListStruct*)GetWindowLong( hWnd, 0 );
这时,als结构可能已经不是你new出来得AttrListStruct得地址,当然里面得hWnd也已经无效.
所以既然als得地址已经不是new出来得或则是0,那么访问它肯定会非法.
而如果你不是static.每次AttrListProc中得als都不是同一个.所以就算有新消息给AttrListProc
但是WM_CREATE里得那个als始终是WM_CREATE里得.所以不会造成它得地址已改变.所以,不会非法.

#8


我查了一下,应该是收到了 WM_PARENTNOTIFY 
然后 als = (AttrListStruct*)GetWindowLong( hWnd, 0 );
这时als得地址指向了0.而你一边还在 als->hWnd = 某值.
所以非法

#9


als = (AttrListStruct*)GetWindowLong( hWnd, 0 );
检查一下als是否有效.

如果注册窗口类时窗口附加字节设为了0,则用GetWindowLong(hWnd,0)无法取得SetWindowLong(hWnd, 0, (LONG_PTR)data);保存的值

#10


CODE2002(′單純丶.) 
果然如你说的.谢了.

#1


越界了?

#2


new的时候 是否成功?
AttrListStruct 是否太大? 

非法内存访问, 调试时看汇编代码到底是访问了哪个地址?

#3


我上面应该说清楚了吧.

当执行到als->Selection = 0;的时候,指针是指向一个合法的地址的,而且这句执行正常
然后执行到als->hwndEdit = CreateWindow(...)这句的时候,als突然变成了0.

#4


非静态,那就确定是CreateWindow这个函数越界了,你看看参数。
将栈上的内容给替换掉了。

#5


这个是系统API,越界的可能性不大吧.而且即使越界,也不可能影响到静态存储区.

#6


你不是这样说的么?
并且如果als不是static的,就不会有非法内存访问的问题.


这个是系统API,越界的可能性不大吧.而且即使越界,也不可能影响到静态存储区.
===============================
怎么不可能
char sz[16]
GetWindowTextA( , sz , 256);假如窗口标题大小超过16,会不会越界?

#7


我觉得问题在于
als = (AttrListStruct*)GetWindowLong( hWnd, 0 );
当程序调用了CreateWindow的时候,这时主窗口创建了一个Edit.
这个Edit是主窗口得子窗口,那么应该会产生一些消息.
所以CreateWindow得同时,或则CreateWindow之后,AttrListProc收到了一个建立子窗口得消息.
而在处理这个消息得时候.als = (AttrListStruct*)GetWindowLong( hWnd, 0 );
这时,als结构可能已经不是你new出来得AttrListStruct得地址,当然里面得hWnd也已经无效.
所以既然als得地址已经不是new出来得或则是0,那么访问它肯定会非法.
而如果你不是static.每次AttrListProc中得als都不是同一个.所以就算有新消息给AttrListProc
但是WM_CREATE里得那个als始终是WM_CREATE里得.所以不会造成它得地址已改变.所以,不会非法.

#8


我查了一下,应该是收到了 WM_PARENTNOTIFY 
然后 als = (AttrListStruct*)GetWindowLong( hWnd, 0 );
这时als得地址指向了0.而你一边还在 als->hWnd = 某值.
所以非法

#9


als = (AttrListStruct*)GetWindowLong( hWnd, 0 );
检查一下als是否有效.

如果注册窗口类时窗口附加字节设为了0,则用GetWindowLong(hWnd,0)无法取得SetWindowLong(hWnd, 0, (LONG_PTR)data);保存的值

#10


CODE2002(′單純丶.) 
果然如你说的.谢了.