为什么使用指针调用 GetWindowRect 会导致异常,而地址不会
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
gettwindowrect期望调用者拥有矩形结构
在你的原始版本中,你的*Rect
没有指向任何有效的内存。所以当你试图使用它时,你是在访问一些不属于你的随机内存块。操作系统对此予以否认。我只是很惊讶对GetWindowRect
的调用没有导致崩溃。
另一方面,您的更新版本声明RECT Rect
,它在堆栈上分配内存。该内存在函数调用时自动分配,并在函数结束时清理。
澄清一下,这个问题与指针和引用之间的差异无关。这个问题完全是由内存分配/所有权引起的。
相关文章:
- 将数组的地址分配给变量并删除
- 空基优化子对象的地址
- 处理多个异常集合的C++方法
- 我在c++代码中生成了一个运行时#3异常
- C++ 指针的内存地址和指向数组的内存地址如何相同?
- 孤立代码块在结构中引发异常
- C++中的赋值发生,尽管右侧出现异常
- 在C++中打印指向不同基元数据类型的指针的内存地址
- 如何在c++程序中找到函数的地址
- 从构造函数抛出异常时如何克服内存泄漏
- 删除无效地址时C++引发异常
- 读取 MAC 地址时文件读取异常
- 使用双LL在C++中实现Stack失败,出现异常"EXC_BAD_ACCESS(代码=2,地址=0x7fff5
- 在无效地址上,boost::asio::ip:::address::from_string 没有引发异常
- C 错误:0x00934ABB(链接列表,地址簿)的未手动异常
- (内存地址)(msvcr110.dll)处出现未处理的异常
- 地址族不支持异常重现
- C++异常处理通过引用传递:抛出的地址与捕获的地址不同
- 为什么使用指针调用 GetWindowRect 会导致异常,而地址不会
- 在不直接修改地址的情况下执行地址时引发异常