简体   繁体   English

为什么用指针调用GetWindowRect会导致异常,但地址却没有

[英]Why does calling GetWindowRect with pointer cause exception but address doesn't

I have a utility function in a dll to center my form on the host applications screen. 我在dll中有一个实用程序功能,可将窗体放在主机应用程序屏幕上。 I'm using RAD Studio XE2. 我正在使用RAD Studio XE2。 I have to do it manually because the host application is non-VCL and the form placement parameters of the TForm don't work properly. 我必须手动执行此操作,因为主机应用程序是非VCL并且TForm的表单放置参数无法正常工作。 The code below works. 下面的代码有效。 Both functions are declared static, and I've previously set the Application handle property to the host app. 这两个函数都声明为静态,并且我之前已将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;
         }
      }
   }

My initial GetAppCenter code used a Rect * instead and returned the correct value, but threw an Access Violation exception when I set f->Left. 我最初的GetAppCenter代码使用Rect *代替并返回正确的值,但是当我设置f-> Left时抛出了访问冲突异常。 Can anyone explain why? 谁能解释为什么?

   // 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 

This is incorrect. 这是不正确的。 GetWindowRect needs a valid RECT* argument so that it fills memory pointed to by this pointer. GetWindowRect需要一个有效的RECT*参数,以便它填充此指针指向的内存。 You are instead passing an uninitialized pointer expecting that some magic will make it valid. 相反,您传递的是未初始化的指针,期望有某种魔术使之有效。 Instead you are getting access violation. 相反,您遇到访问冲突。 You need: 你需要:

  RECT Rect;
  GetWindowRect(Application->Handle, &Rect); // <<--- Note &
  //Rect.left 

GetWindowRect expects the caller to own the rectangle structure. GetWindowRect期望调用方拥有矩形结构。

In your original version, your *Rect does not point to any valid memory. 在您的原始版本中,您的*Rect不会指向任何有效的内存。 So when you try to use it, you're accessing some random block of memory that you don't own. 因此,当您尝试使用它时,您正在访问一些您不拥有的随机存储器。 The operating system denies this. 操作系统否认这一点。 I am just surprised that the call to GetWindowRect doesn't cause the crash. 我只是惊讶地发现对GetWindowRect的调用不会导致崩溃。

On the other hand, your updated version declares RECT Rect , which allocates memory on the stack. 另一方面,更新后的版本声明RECT Rect ,它在堆栈上分配内存。 That memory is automatically allocated when your function is called, and is cleaned up when your function finishes. 该内存在调用函数时自动分配,并在函数完成时清除。

To clarify, this problem doesn't have to do with differences between pointer and reference. 需要澄清的是,此问题与指针和引用之间的差异无关。 The problem is exclusively due to memory allocation / ownership. 问题完全是由于内存分配/所有权。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 为什么在分配了&#39;new&#39;的指针上调用free()会导致堆损坏? - Why does calling free () on a pointer allocated with 'new' cause heap corruption? 为什么指针不写类的地址? - Why doesn't the pointer write the address of the class? 为什么指向指针的已解除引用的std :: cout导致-fsanitize = address发出投诉? - Why does std::cout of a dereferenced pointer to pointer cause -fsanitize=address to complain? 我将一个变量分配给存储在指针地址中的值,那么为什么当初始值改变时它不改变呢? - I assigned a variable to the value of what is stored at a pointer's address, so why doesn't it change when the initial value does? 如果涉及抽象类,为什么指向派生的指针和指向基的指针不指向相同的地址? - Why doesn't a pointer to derived and a pointer to base point to the same address if abstract classes are involved? 为什么“动态异常”保证会导致开销? - Why does “dynamic exception” guarantee cause overhead? 为什么mglData会导致BAD ACCESS异常? - Why does mglData cause a BAD ACCESS exception? 为什么此指针包含存储在堆中的地址? - Why does this pointer contain an address stored on the heap? 为什么打印指针地址会触发断点? - Why does printing a pointer address trigger a breakpoint? 为什么指针地址的输出不同? - why does output of an address of pointer is different?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM