Winapi 回调中的Win32 API向量问题

Winapi 回调中的Win32 API向量问题,winapi,stdvector,Winapi,Stdvector,在我的程序的WndProc回调中,我这样做是为了将鼠标单击存储在向量中: case WM_LBUTTONDOWN: point = new POINT(); point->x = LOWORD (lParam); point->y = HIWORD (lParam); point_vector.push_back(point); InvalidateRect(hWnd, NULL, TRUE); break; 它编译得很好,但是当

在我的程序的WndProc回调中,我这样做是为了将鼠标单击存储在向量中:

case WM_LBUTTONDOWN:
    point = new POINT();
    point->x = LOWORD (lParam);
    point->y = HIWORD (lParam);

    point_vector.push_back(point);

    InvalidateRect(hWnd, NULL, TRUE);
    break;
它编译得很好,但是当它运行时,我在“push_back”上遇到了访问冲突。“point”和“point_vector”都是全局声明的,在调试器中似乎有效。如果我在本地声明它们,就没有访问冲突。为什么会发生这种情况

这是VS10

@马丁洛弗尔 这是调用堆栈

msvcr100d.dll!运算符删除(Vult*PUSEDATABAS= 0xFEFEFE)行52 +0x3字节C++ 我的app.exe!STD::分配器::DeloPoint(TAGPOINT **PtR= 0xFEFEFEFE,无符号int <强>正规=0)行182 +0x9字节C++ 我的app.exe!STD::向量>::保留(无符号int=1)768行C++ 我的app.exe!STD::向量>::(1)1298号C++ 我的app.exe!STD::向量>:推送(TAGPONT * const和yVal= 0x00 8E9D58)992行C++ 我的app.exe!WndProc(HWND < /StRe> *HWND= 0x000 0B060A,未签名INT消息=513,未签名int WPARAM=1,长LPAARAM=19857987)行241 C++ user32.dll!774662fa()
[下面的帧可能不正确和/或丢失,没有为user32.dll加载符号]
user32.dll!77466d3a()
user32.dll!77466ce9()
user32.dll!77466e44()
user32.dll!774677c4()
user32.dll!7746788a()
我的app.exe!WWINMANT(HINSTANSYS**HStutial0x00 C8000,HistSnasyx**HPROSPATE=0x00亿,WCHARYT*LPCMDLINE 0x00 6C35D2,INTnCMDSt= 1)行62 +0xC字节C++ 我的app.exe__tmainCRTStartup()行547+0x2c字节C 我的app.exe!wwinmincartstartup()行371 C 内核32.dll!764c33ca()
ntdll.dll!77e79ed2()
ntdll.dll!77e79ea5()

这是它在dbgdel.cpp中崩溃的一行(不确定这是否有用) /*验证块类型*/ _ASSERTE(_BLOCK_TYPE_有效(pHead->nBlockUse))

@CoreyStup 如果变量是本地的或全局的,似乎没有任何区别


如果调用其他向量函数,如resize()、clear()或reserve(),而不是size(),也会发生这种情况。

好的,解决了它。我在节目的另一部分打电话:

_stprintf_s(msgbuf, 1024, _T("Mouse coordinates: %d %d\0"), mouse.x, mouse.y);
应该是

_stprintf_s(msgbuf, sizeof(msgbuf), _T("Mouse coordinates: %d %d\0"), mouse.x, mouse.y);
这导致某种内存损坏,因为msgbuf长度!=1024

我真是个笨蛋,向大家道歉

“点”和“点向量”。。。在调试器中似乎有效

  • 以什么标准衡量,你认为它们是有效的?callstack的含义正好相反
  • 在你第一次尝试推回你之前是什么样子的
这是调用堆栈的顶部:

6. msvcr100d.dll!operator delete(void * pUserData=0xfefefefe) Line 52 + 0x3 bytes C++
5. my_app.exe!std::allocator::deallocate(tagPOINT * * _Ptr=0xfefefefe, unsigned int formal=0) Line 182 + 0x9 bytes C++
4. my_app.exe!std::vector >::reserve(unsigned int _Count=1) Line 768 C++
3. my_app.exe!std::vector >::_Reserve(unsigned int _Count=1) Line 1298 C++
2. my_app.exe!std::vector >::push_back(tagPOINT * const & _Val=0x008e9d58) Line 992 C++
1. my_app.exe!WndProc(HWND * hWnd=0x000b060a, unsigned int message=513, unsigned int wParam=1, long lParam=19857987) Line 241 C++
让我们从一开始就检查它:

1. my_app.exe!WndProc(HWND * hWnd=0x000b060a, unsigned int message=513, unsigned int wParam=1, long lParam=19857987) Line 241 C++
在上面的1中,WM_LBUTTONDOWN到达WndProc

2. my_app.exe!std::vector >::push_back(tagPOINT * const & _Val=0x008e9d58) Line 992 C++
在上面的第2部分中,您使用指向堆上新创建的点实例的指针调用push_back

3. my_app.exe!std::vector >::_Reserve(unsigned int _Count=1) Line 1298 C++
在上面的3中,push_back调用内部函数_Reserve(计数为1),为1
点*
分配内存。这是因为向量是空的,因为还没有添加任何元素,并且这个特定向量实例分配器的指数增长方案从1开始。(添加另一个元素将重新分配新内存,并将第一个元素加上新的元素复制到那里。)

在上面的4中,_Reserve将其调用转发给Reserve函数

5. my_app.exe!std::allocator::deallocate(tagPOINT * * _Ptr=0xfefefefe, unsigned int formal=0) Line 182 + 0x9 bytes C++
在上面的5中,在为第一个
点*
分配了空间之后,reserve看到内部向量数据指针(在VS 2010中,它的名称是
\u Myfirst
)是非空的(参见上面的_Ptr=0xfefefefe),因此在将其指向刚刚分配的新空间之前,必须释放0(!)
点*
元素的旧空间

不幸的是,allocator::deallocate忽略了0个元素将被释放(可能是no-op),并愉快地尝试删除0xfefe

6. msvcr100d.dll!operator delete(void * pUserData=0xfefefefe) Line 52 + 0x3 bytes C++
在上面的第6节中,0xFEFE不幸是已释放内存的VS debug表示形式,因此删除阻塞。它还能做什么

  • 但为什么内部向量数据指针是0xfefe
  • 在尝试推回之前,你对向量做了什么
  • 你到底是怎么声明向量的

很奇怪。

FWIW您的代码片段对我来说很好。为什么要动态分配像
POINT
这样的小类型?复制可能比传递指针快。崩溃的调用堆栈是什么?我猜全局点向量在某处被内存击溃了。如果一次移动一个点和一个点作为本地点,它的行为会有所不同吗?如何声明点向量?它是指向点的指针向量还是仅仅是点向量?@Johann:st\u printf\u s什么时候开始释放任何东西了?当然,它会覆盖您传入的缓冲区,直到您提供的长度为止。
6. msvcr100d.dll!operator delete(void * pUserData=0xfefefefe) Line 52 + 0x3 bytes C++