order of variable deletion and creation
Show older comments
Is the order in which the left hand side is deleted and the right hand side executed defined?
i.e.
output = createNewOutput();
If "output" exists, does it get deleted first, before createNewOutput runs? Or alternatively, does createNewOutput run before output is deleted? Is this behavior undefined?
Accepted Answer
More Answers (2)
James Tursa
on 24 Jul 2017
Edited: James Tursa
on 24 Jul 2017
I don't think this behavior is formally documented. My observations have been that the mxArray structure for "output" is retained, but the internal values of the mxArray get replaced by whatever gets returned by createNewOutput. E.g.,
>> format debug
>> x = 1:3
x =
Structure address = 6effc58
m = 1
n = 3
pr = 2d3ee750
pi = 0
1 2 3
>> x = 4:6
x =
Structure address = 6effc58
m = 1
n = 3
pr = 2d3f4cc0
pi = 0
4 5 6
>> x = single(7:9)
x =
Structure address = 6effc58
m = 1
n = 3
pr = 26f51950
pi = 0
7 8 9
Here you can see that the mxArray struct for "output" lives at 6effc58. And through all of the assignments that doesn't change. But the data pointer pr does change with each new assignment. I would hazard a guess that this is the order in which things take place:
1) createNewOutput executes and creates a new temporary "result"
2) "output" gets turned into a shared data copy of "result"
3) the temporary "result" gets destroyed
So for step 1, my guess is that both data blocks of "output" and "result" exist in memory at the same time, and the original data block of "output" doesn't get free'd until step 2. This seems to be borne out by the following example (but maybe different behavior could occur in different circumstances such as functions operating "in-place" on a variable):
>> n = 500*1024*1024/8
n =
65536000
>> memory
Maximum possible array: 2045 MB (2.144e+009 bytes) *
Memory available for all arrays: 3220 MB (3.376e+009 bytes) **
Memory used by MATLAB: 600 MB (6.294e+008 bytes) <-- start with 600 MB used
Physical Memory (RAM): 32690 MB (3.428e+010 bytes)
* Limited by contiguous virtual address space available.
** Limited by virtual address space available.
>> x = zeros(n,1);
>> memory
Maximum possible array: 1545 MB (1.620e+009 bytes) *
Memory available for all arrays: 2720 MB (2.852e+009 bytes) **
Memory used by MATLAB: 1100 MB (1.154e+009 bytes) <-- Add a 500 MB array
Physical Memory (RAM): 32690 MB (3.428e+010 bytes)
* Limited by contiguous virtual address space available.
** Limited by virtual address space available.
>> x = createNewOutput(n);
Maximum possible array: 1044 MB (1.095e+009 bytes) *
Memory available for all arrays: 2220 MB (2.328e+009 bytes) **
Memory used by MATLAB: 1600 MB (1.678e+009 bytes) <-- another 500 MB inside of function
Physical Memory (RAM): 32690 MB (3.428e+010 bytes)
* Limited by contiguous virtual address space available.
** Limited by virtual address space available.
>> memory
Maximum possible array: 1044 MB (1.095e+009 bytes) *
Memory available for all arrays: 2720 MB (2.852e+009 bytes) **
Memory used by MATLAB: 1100 MB (1.154e+009 bytes) <-- back down to only one 500 MB added block
Physical Memory (RAM): 32690 MB (3.428e+010 bytes)
* Limited by contiguous virtual address space available.
** Limited by virtual address space available.
If you want to force MATLAB to clear the "output" data memory first so two large data blocks will not be in memory at the same time, then you should probably do this prior to calling createNewOutput:
output = [];
That way the mxArray struct is still retained (as MATLAB seems to like to do) but the original data block gets free'd first.
John D'Errico
on 24 Jul 2017
I assume you are asking this if there is a bug in the right hand side. Will MATLAB have already deleted the output variable?
The answer is MATLAB performs the operation on the right hand side, BEFORE it does an assignment, also before the left hand side is replaced. So the right hand side is created before MATLAB worries about where the result will be stuffed.
A simple test of this is:
L = rand(10,1);
L(2:3) = rand(2,2)
In an assignment A(:) = B, the number of elements in A and B must be the same.
L
L =
0.43874
0.38156
0.76552
0.7952
0.18687
0.48976
0.44559
0.64631
0.70936
0.75469
So MATLAB did not think about if the result would even fit into the left hand side, until the RHS existed.
You might argue that might not be a good test of the behavior you are asking about, since MATLAB might do things differently in other cases. But it is equally easy to write a simple function with an error in it.
fun = @(x) x(:,2);
A = ones(10,1);
X = rand(10,1);
A = fun(X)
Index exceeds matrix dimensions.
Error in @(x)x(:,2)
>> A
A =
1
1
1
1
1
1
1
1
1
1
So, A was created as a column vector of all ones. Then create X as a column vector with ONE column, and a function that extracts column 2 of the input. So, if I try to use this function to overwrite A, the function result must fail, BEFORE a result exists. If MATLAB were to delete A first before the function was executed, then A will not exist.
As you can see in the test, A is still the vector of ones it was before I tried to replace it, thus confirming my claim.
Categories
Find more on Whos in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!