0

在进入方法之前,我需要对以下内存访问冲突进行一些理论解释:

String testMethod (AnsiString param1);
AnsiString A1 = testMethod(A1);

我试图理解问题背后的理论。

A1被 while 的返回值初始化,testMethod()同时它被传递给testMethod(). 在实际输入方法之前会发生什么?当传递给testMethod()它时没有实际值/随机值,是吗?创建了一个本地副本A1,实际上在该过程中是否发生异常?

尝试调试,输入了很多AnsiString, UnicodeString, 和AnsiStringBase方法。

为什么它会起作用,当我以这种方式更改方法签名时:

AnsiString testMethod (AnsiString param1);
4

2 回答 2

1

AnsiString A1 = testMethod(A1);只是未定义的行为,无论是testMethod()返回String还是AnsiString. 没有理由为什么它会以一种方式而不是另一种方式崩溃。只是不要这样做,期间!您正在尝试将 to 的副本A1传递给尚未构建的testMethod()之前。A1

于 2021-10-06T16:36:41.780 回答
1

AnsiString A1 = testMethod(A1);

当您到达这一点时:
AnsiString A1
名称A1存在并且编译器知道。因此,您可以在更右侧使用它。但是,您正在调用testMethod尚未构建的原始内存块。当它遇到试图读取内部成员的复制构造函数时,它会爆炸A1

这里有一个详细说明:虽然都写在一行上,但是你有几个步骤在进行,事情在不同的时间处理。

在编译时,一组字节被放在一边,并使用标签A1来引用它们。

在运行时,会执行一条语句来初始化A1. 这是通过调用一个构造函数来工作的,该构造函数被设计为期望原始内存并负责将该内存变成该类型的合法实例。

但是,在这种情况下,获取用于初始化此变量的值,它使用A1作为参数传递的函数调用。但是A1还没有初始化。

在另一个细节层次上,代码是通过以下方式实现的:返回类类型的函数是通过将结果区域的地址作为另一个参数传递来实现的。的定义A1导致编译器为此留出内存,但尚未对其进行任何处理。在执行的这一点上,它调用一个函数__impl_testMethod(&A1, copy_of(A1));

尝试调试,输入了很多AnsiString、UnicodeString、AnsiStringBase方法。

您正在看到复制构造函数在起作用。您可能真的想将其定义为:

String testFunction (const AnsiString& param1);
因为如果该函数将查看它但不修改其自己的私有副本 ,则没有理由将对象复制到其中。param1

而且,C++ 没有“方法”,而是成员函数,而且这甚至都不是成员函数(据我在你的 OP 中看到的)。它被恰当地描述为“免费功能”。

于 2021-10-06T16:43:50.197 回答