未初始化变量的访问冲突被传递给初始化它的方法调用
Access Violation with uninitialized variable being passed to method call that initializes it
在进入该方法之前,我需要对以下内存访问冲突进行一些理论上的解释:
String testMethod (AnsiString param1);
AnsiString A1 = testMethod(A1);
我正在尝试了解问题背后的理论。
A1
由 testMethod()
的 return 值初始化,同时它被传递给 testMethod()
。在实际进入方法之前会发生什么?当传递给 testMethod()
它没有实际的 value/a 随机值,是吗?创建了 A1
的本地副本,实际上在该过程中是否发生异常?
尝试调试,进入了很多AnsiString
、UnicodeString
、AnsiStringBase
方法
当我以这种方式更改方法签名时,为什么它会起作用:
AnsiString testMethod (AnsiString param1);
AnsiString A1 = testMethod(A1);
只是 未定义的行为 ,无论是 testMethod()
returns String
还是 AnsiString
。没有理由为什么它会以一种方式崩溃而不是另一种方式。只是不要这样做,时期!在构建 A1
之前,您正试图将 A1
的 copy 传递给 testMethod()
。
AnsiString A1 = testMethod(A1);
当你到达这个点时:
AnsiString A1
名称 A1
存在并且为编译器所知。因此,您可以在更右边使用它。但是,您正在使用尚未构建的原始内存块调用 testMethod
。当它遇到试图读取 A1
.
中的成员的复制构造函数时,它会爆炸
这里有一个详细说明:虽然它全部写在一行上,但您有几个步骤在进行,事情在不同的时间处理。
在编译时,一组字节被放在一边,标签A1
用来引用它们。
在运行时,执行一条语句初始化A1
。这是通过调用构造函数来实现的,该构造函数旨在期望原始内存并负责将该内存变成该类型的合法实例。
但是,在这种情况下,要获取用于初始化此变量的值,它会使用将 A1
作为参数传递的函数调用。但是A1
还没有初始化
在另一个细节层次上,代码是通过以下方式实现的:返回 class 类型的函数是通过将结果区域的地址作为另一个参数传递来实现的。 A1
的定义导致编译器为此留出内存,但尚未对其进行任何处理。在执行的这一点上,它调用了一个函数 __impl_testMethod(&A1, copy_of(A1));
.
Trying to debug, a lot of AnsiString, UnicodeString, and AnsiStringBase methods are entered.
您看到了正在运行的复制构造函数。您可能真的想将其定义为:
String testFunction (const AnsiString& param1);
因为没有理由 将对象复制 到 param1
如果该函数将查看它但不修改它自己的私有副本。
并且,C++ 没有“方法”,而是成员函数,而且这甚至不是成员函数(据我在您的 OP 中所见)。它被恰当地描述为“免费功能”。
在进入该方法之前,我需要对以下内存访问冲突进行一些理论上的解释:
String testMethod (AnsiString param1);
AnsiString A1 = testMethod(A1);
我正在尝试了解问题背后的理论。
A1
由 testMethod()
的 return 值初始化,同时它被传递给 testMethod()
。在实际进入方法之前会发生什么?当传递给 testMethod()
它没有实际的 value/a 随机值,是吗?创建了 A1
的本地副本,实际上在该过程中是否发生异常?
尝试调试,进入了很多AnsiString
、UnicodeString
、AnsiStringBase
方法
当我以这种方式更改方法签名时,为什么它会起作用:
AnsiString testMethod (AnsiString param1);
AnsiString A1 = testMethod(A1);
只是 未定义的行为 ,无论是 testMethod()
returns String
还是 AnsiString
。没有理由为什么它会以一种方式崩溃而不是另一种方式。只是不要这样做,时期!在构建 A1
之前,您正试图将 A1
的 copy 传递给 testMethod()
。
AnsiString A1 = testMethod(A1);
当你到达这个点时:
AnsiString A1
名称 A1
存在并且为编译器所知。因此,您可以在更右边使用它。但是,您正在使用尚未构建的原始内存块调用 testMethod
。当它遇到试图读取 A1
.
这里有一个详细说明:虽然它全部写在一行上,但您有几个步骤在进行,事情在不同的时间处理。
在编译时,一组字节被放在一边,标签A1
用来引用它们。
在运行时,执行一条语句初始化A1
。这是通过调用构造函数来实现的,该构造函数旨在期望原始内存并负责将该内存变成该类型的合法实例。
但是,在这种情况下,要获取用于初始化此变量的值,它会使用将 A1
作为参数传递的函数调用。但是A1
还没有初始化
在另一个细节层次上,代码是通过以下方式实现的:返回 class 类型的函数是通过将结果区域的地址作为另一个参数传递来实现的。 A1
的定义导致编译器为此留出内存,但尚未对其进行任何处理。在执行的这一点上,它调用了一个函数 __impl_testMethod(&A1, copy_of(A1));
.
Trying to debug, a lot of AnsiString, UnicodeString, and AnsiStringBase methods are entered.
您看到了正在运行的复制构造函数。您可能真的想将其定义为:
String testFunction (const AnsiString& param1);
因为没有理由 将对象复制 到 param1
如果该函数将查看它但不修改它自己的私有副本。
并且,C++ 没有“方法”,而是成员函数,而且这甚至不是成员函数(据我在您的 OP 中所见)。它被恰当地描述为“免费功能”。