可以省略“^”吗?当访问记录指针的成员时会导致访问冲突吗?

发布于 2024-10-27 13:09:22 字数 751 浏览 1 评论 0原文

在 VirtualTreeview 中,我将数据存储在 PVirtualNodes 中。我在我的应用程序中遇到了几次访问冲突(通常是“读取地址 00000000”),并且它们大多数(我实际上敢说总是)发生在我使用节点数据执行某些操作时。

然而,问题是,我声明了我的东西&像这样使用它:

// DUMMY CODE - Not written or tested in IDE
var
 MyNode : PVirtualNode;
 MyData : PMyNodeData;
Begin
 MyNode := VST.GetFirstSelected;

 if Assigned(MyNode) then
  Begin
   MyData := VST.GetNodeData(MyNode);
   if Assigned(MyData) then
   Begin
     MyData.DummyProperty := 'Test';
   End;
  End;
End;

正如您可能注意到的那样,我不会通过执行MyData^“取消引用”(正确吗?)我的“MyData”!我不这样做的原因是有人告诉我没有必要将插入符号添加到指针名称中,但我有一种感觉,它与此有关。如果我知道的话,我就不会在这里发帖了。 ;)

所以我的问题是:最终是否有必要将小 ^ 添加到 MyData 中?如果不这样做,我是否可能会引发访问冲突?

In VirtualTreeview, I am storing my data in the PVirtualNodes. I have experienced several Access Violations (typically with "Read of adress 00000000") in my App, and they mostly (I'd actually dare to say Always) occur when I am doing something with my Node Data.

However, the thing is, I declare my stuff & use it like this:

// DUMMY CODE - Not written or tested in IDE
var
 MyNode : PVirtualNode;
 MyData : PMyNodeData;
Begin
 MyNode := VST.GetFirstSelected;

 if Assigned(MyNode) then
  Begin
   MyData := VST.GetNodeData(MyNode);
   if Assigned(MyData) then
   Begin
     MyData.DummyProperty := 'Test';
   End;
  End;
End;

As you probably noticed, I do not "dereference" (correct?) my "MyData" by doing MyData^! The reason I don't is that I have been told it was not necessary to add the caret to the pointer name, however I have a feeling that it has something to do with it. If I knew, I wouldn't be posting on here. ;)

So my question is: Is it in the end necessary to add the little ^ to MyData? And is it possible that by not doing that, I may provoke an Access Violation?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

韬韬不绝 2024-11-03 13:09:22

当你有一个指向记录的指针时,你可以省略^。以下是等效的:

MyData.DummyProperty
MyData^.DummyProperty

对于已弃用的 Turbo Pascal object 也是如此。我希望 Delphi 类也是如此,尽管我从未尝试过它们,因为它们已经是引用类型。

遗憾的是,这不是对您的 AV 的解释。

When you have a pointer to a record, then you can omit the ^. The following are equivalent:

MyData.DummyProperty
MyData^.DummyProperty

This is also the case for the deprecated Turbo Pascal object. I would expect it to be so for Delphi classes, although I have never tried with them since they are already reference types.

Sadly, this is not the explanation for your AV.

说谎友 2024-11-03 13:09:22

使用 ^ 取消引用记录是可选的,因为编译器隐式假定它。当不使用任何硬类型转换时,任何需要“^”的情况都将无法编译。但只有 1 级解引用是隐式的。

type
  TMyRecord  = record
    MyField : Integer;
  end;
  PMyRecord = ^TMyRecord;
  PPMyRecord = ^PMyRecord;

procedure DoSomething;
var vMyField : PPMyRecord;
begin
  vMyField.MyField;  <---Won't compile
  vMyField^.MyField; <---Will compile
end;

至于您的访问冲突,这是我根据您所写内容的最佳猜测...假设您的示例具有代表性(即分配字符串时崩溃),并假设 PMyNodeData 指向一条记录。我猜测 PMyNodeData 的内存是用“GetMem”而不是“New”保留的,导致记录的字符串字段未初始化。

Using ^ to dereference records is optionnal as it is assumed implicitly by the compiler. When not using any hard typecast, any situation that would requires the "^" would not compile. But only 1 level of dereferencing is implicit.

type
  TMyRecord  = record
    MyField : Integer;
  end;
  PMyRecord = ^TMyRecord;
  PPMyRecord = ^PMyRecord;

procedure DoSomething;
var vMyField : PPMyRecord;
begin
  vMyField.MyField;  <---Won't compile
  vMyField^.MyField; <---Will compile
end;

As for your access violation, here's my best guess based on what you wrote... Assuming your exemple is representative (i.e. that is, crash on assigning a string), and assuming PMyNodeData points to a record. I'd guess that PMyNodeData's memory was reserved with "GetMem" instead of "New", making the string field of the record uninitialized.

笑叹一世浮沉 2024-11-03 13:09:22

有一个例外,Data.xxData^.xx 不相同:当指向的字段是相同指针类型或通用指针类型时:

var
  x: PPointer;
  y: Pointer;
begin
  x := GetPPointer();
  y := x;
  y := x^;
end;

I最好的做法是在使用指向值时始终添加运算符 ^ 以避免出现上述不明确的情况。

鉴于您的示例:问题可能是内存损坏。您是否正确设置了NodeDataSize

There is an exception where Data.xx and Data^.xx are not the same: when the field pointed at is of the same pointer type or the generic pointer type:

var
  x: PPointer;
  y: Pointer;
begin
  x := GetPPointer();
  y := x;
  y := x^;
end;

I consider it best practice to always add the operator ^ when the pointed value is used to avoid ambiguous situations like above.

Given your example: The problem is possibly memory corruption. Did you set NodeDataSize correctly?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文