![](/img/trans.png)
[英]Why does calling free () on a pointer allocated with 'new' cause heap corruption?
[英]Why does calling GetWindowRect with pointer cause exception but address doesn't
我在dll中有一個實用程序功能,可將窗體放在主機應用程序屏幕上。 我正在使用RAD Studio XE2。 我必須手動執行此操作,因為主機應用程序是非VCL並且TForm的表單放置參數無法正常工作。 下面的代碼有效。 這兩個函數都聲明為靜態,並且我之前已將Application handle屬性設置為主機應用程序。
void MyClass::GetAppCenter(POINT * pos) {
RECT Rect;
GetWindowRect(Application->Handle, &Rect);
pos->x = (Rect.left + Rect.right) / 2;
pos->y = (Rect.top + Rect.bottom) / 2;
}
void MyClass::PlaceForm(TForm * f) {
POINT pos;
GetAppCenter(&pos);
for (int i = 0; i < Screen->MonitorCount; i++) {
TRect r = Screen->Monitors[i]->WorkareaRect;
if (r.Contains(pos)) {
f->Left = (r.Left + r.Right) / 2 - f->Width / 2;
f->Top = (r.Top + r.Bottom) / 2 - f->Height / 2;
return;
}
}
}
我最初的GetAppCenter代碼使用Rect *代替並返回正確的值,但是當我設置f-> Left時拋出了訪問沖突異常。 誰能解釋為什么?
// original version
void OasisUtils::GetOasisCenter(POINT * pos) {
RECT *Rect;
GetWindowRect(Application->Handle, Rect);
pos->x = (Rect->left + Rect->right) / 2;
pos->y = (Rect->top + Rect->bottom) / 2;
delete Rect; // tried with and without this
}
RECT *Rect;
GetWindowRect(Application->Handle, Rect);
//Rect->left
這是不正確的。 GetWindowRect
需要一個有效的RECT*
參數,以便它填充此指針指向的內存。 相反,您傳遞的是未初始化的指針,期望有某種魔術使之有效。 相反,您遇到訪問沖突。 你需要:
RECT Rect;
GetWindowRect(Application->Handle, &Rect); // <<--- Note &
//Rect.left
GetWindowRect期望調用方擁有矩形結構。
在您的原始版本中,您的*Rect
不會指向任何有效的內存。 因此,當您嘗試使用它時,您正在訪問一些您不擁有的隨機存儲器。 操作系統否認這一點。 我只是驚訝地發現對GetWindowRect
的調用不會導致崩潰。
另一方面,更新后的版本聲明RECT Rect
,它在堆棧上分配內存。 該內存在調用函數時自動分配,並在函數完成時清除。
需要澄清的是,此問題與指針和引用之間的差異無關。 問題完全是由於內存分配/所有權。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.