2011-06-13 49 views
3

在我的程序的WndProc的回調,我這樣做是爲了保存鼠標點擊的載體:Win32 API的向量問題

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上。

@Martyn Lovell的 這裏是在調用堆棧

msvcr100d.dll!操作者刪除(無效* pUserData = 0xfefefefe)線52 + 0x3字節C++ my_app.exe!性病::分配器::解除分配(tagPOINT * * _Ptr = 0xfefefefe,unsigned int formal = 0)行182 + 0x9字節C++ my_app.exe!std :: vector> :: reserve(unsigned int _Count = 1)行768 C++ my_app.exe!std :: vector> :: _ Reserve(unsigned int _Count = 1)Line 1298 C++ my_app.exe!std :: vector> :: push_back(tagPOINT * const & _Val = 0x008e9d58)Line 992 C++ my_app.exe!的WndProc(HWND *的hWnd = 0x000b060a,無符號整型消息= 513,無符號整型的wParam = 1,長的lParam = 19857987)線241 C++ USER32.DLL!774662fa()
[相框下面可能不正確和/或缺失,沒有加載USER32.DLL]符號
USER32.DLL!77466d3a()
USER32.DLL!77466ce9()
USER32.DLL!77466e44()
USER32.DLL!774677c4()
user32.dll!7746788a()
my_app.exe!wWinMain(HINSTANCE__ * hInstance = 0x00c80000,HINSTANCE__ * hPrevInstance = 0x00000000,wchar_t * lpCmdLine = 0x006c35d2,int nCmdShow = 1)線路62個+位於0xC字節C++ my_app.exe!__ tmainCRTStartup()線547 + 0x2c上字節Ç my_app.exe!wWinMainCRTStartup()線371℃ KERNEL32.DLL!764c33ca()
NTDLL.DLL!77e79ed2( )
ntdll.dll的!77e79ea5()

而這正是它在dbgdel.cpp崩潰行(不知道這是有幫助的) /*驗證塊類型*/ _ASSERTE(_BLOCK_TYPE_IS_VALID(PHEAD - > nBlockUse));

@CoreyStup 似乎沒有任何區別,如果瓦爾是局部或全局

也出現這種情況,如果我喜歡叫其他調整大小向量函數(),清除()或儲備(),但不尺寸()。

+0

FWIW您的代碼片段對我來說工作正常。 – 2011-06-14 00:19:22

+3

爲什麼你動態地分配像POINT這樣的小類型?複製可能比傳遞指針快。 – 2011-06-14 02:12:52

+0

崩潰的調用堆棧是什麼? – 2011-06-14 05:24:46

回答

0

好的,解決了。在我的程序的不同部分,我打電話:

_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

我這樣的屁股! 。向所有人道歉

+0

@Johann:從什麼時候'_st_printf_s'釋放任何東西?它會覆蓋您傳遞的緩衝區,當然,直到您提供的長度。 – 2011-06-14 22:15:38

1

「point」和「point_vector」...在調試器中似乎都是有效的。

  • 你認爲他們有效的措施是什麼? callstack意味着相反。
  • 在第一次嘗試push_back之前它看起來像什麼?

這是調用堆棧的頂部:

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中,您使用指向堆中新創建的POINT實例的指針調用push_back。

3. my_app.exe!std::vector >::_Reserve(unsigned int _Count=1) Line 1298 C++ 

在上述3中,的push_back調用內部功能_Reserve爲1的計數爲1 POINT*分配內存。這是因爲vector是空的,因爲還沒有添加元素,並且此特定向量實例分配器的指數增長方案從1開始。(添加另一個元素將重新分配新內存並複製第一個元素加上新元素在那裏)

4. my_app.exe!std::vector >::reserve(unsigned int _Count=1) Line 768 C++ 

在上面的4中,_Reserve將其呼叫轉移到備用功能。

5. my_app.exe!std::allocator::deallocate(tagPOINT * * _Ptr=0xfefefefe, unsigned int formal=0) Line 182 + 0x9 bytes C++ 

在上面5中,具有針對第一POINT*分配的空間後,儲備看到,內部矢量數據指針(2010年VS它的名字是_Myfirst)是非空(見上文_Ptr = 0xfefefefe),所以在將它指向剛剛分配的新空間之前,必須釋放0(!)POINT*元素的舊空間。

不幸的是,allocator :: deallocate忽略了0個元素將被解除分配(可能是一個無操作),並樂意嘗試刪除0xfefefefe。

6. msvcr100d.dll!operator delete(void * pUserData=0xfefefefe) Line 52 + 0x3 bytes C++ 

在上面的6中,0xfefefefe很不幸地是已經釋放內存的VS調試表示,所以刪除了扼流圈。它還能做什麼?

  • 但爲什麼內部矢量數據指針0xfefefefe?
  • 你是什麼真的嘗試push_back之前做的向量嗎?
  • 究竟你是如何聲明矢量的?

奇怪的是。