I need some theoretical explanation of the following memory access violation BEFORE even entering the method:
String testMethod (AnsiString param1);
AnsiString A1 = testMethod(A1);
I am trying to understand the theory behind the problem.
A1
is getting initialized by the return value of testMethod()
while at the same time it is passed to testMethod()
. What happens before the method is actually entered? When passed to testMethod()
it has no actual value/a random value, has it? A local copy of A1
is created, does the exception occur during that process, actually?
Trying to debug, a lot of AnsiString
, UnicodeString
, and AnsiStringBase
methods are entered.
Why does it work, when I change the method signature this way:
AnsiString testMethod (AnsiString param1);
CodePudding user response:
AnsiString A1 = testMethod(A1);
is simply undefined behavior, whether testMethod()
returns String
or AnsiString
. There is no reasoning why it crashes one way but not the other. Just don't do it, period! You are trying to pass a copy of A1
to testMethod()
before A1
has been constructed yet.
CodePudding user response:
AnsiString A1 = testMethod(A1);
When you reach this point:
AnsiString A1
the name A1
exists and is known to the compiler. Thus, you can use it farther to the right. However, you are calling testMethod
with a raw memory block that has not been constructed yet. That's going to blow up when it hits the copy constructor which tries to read the members inside A1
.
Here is an elaboration: Although it's all written on one line, you have several steps going on and things handled at different times.
At compilation time, a group of bytes are set aside and the label A1
used to refer to them.
At run time, a statement is executed to initialize A1
. This works by calling a constructor which is designed to expect raw memory and is responsible for making that memory into a legal instance of that type.
However, in this case, obtaining the value to use to initialize this variable it uses the function call which passes A1
as a parameter. But A1
has not been initialized yet.
At another level of detail, the code is realized the following way: A function returning a class type is implemented by passing the address of the result area as another argument. The definition of A1
caused the compiler to set aside memory for that, but nothing has been done with it yet. At this point in the execution, it calls a function __impl_testMethod(&A1, copy_of(A1));
.
Trying to debug, a lot of AnsiString, UnicodeString, and AnsiStringBase methods are entered.
You are seeing the copy constructor in action. You probably really wanted to define it as:
String testFunction (const AnsiString& param1);
because there is no reason to duplicate the object into param1
if that function will be looking at it but not modifying its own private copy.
And, C does not have "methods" but rather member functions, and this isn't even a member function anyway (as far as I can see in your OP). It is properly described as a "free function".