How are structs handled when passed to a function?

11 vues (au cours des 30 derniers jours)
Patrik Ek
Patrik Ek le 17 Déc 2014
Modifié(e) : Bill Tubbs le 2 Mai 2021
Hi, I a question about how structs are handled when they are used as input arguments to functions. I know about "copy on write", namely that matrices are passed by a reference unless they are modified and thus are copied. However, I get the impression that structs actually uses pointers or references to the data fields, and this makes structs different from matrices. This is why I wonder, how are the "copy on write" used when I have struct input arguments?
Examples: 1: matrix)
function out = fun2(in)
out = in; % Return reference
2: matrix)
function out = fun2(in)
in(2,5) = 4; % Matlab creates a copy
out = in;
3: struct, what happens here?)
function out = fun3(in)
in.fieldA = rand(3); % What happens here?
out = in;
  1 commentaire
Adam
Adam le 17 Déc 2014
Modifié(e) : Adam le 17 Déc 2014
When I was looking into this type of behaviour (though not for structs) I just created a matrix large enough that it showed up in my Task Manager memory analysis so I could see at what point a copy of the data was made (if at all) when calling a function.
You should be able to do the same with a struct if you make your fieldA something more like rand(20000).
I haven't investigated structs myself so wouldn't want to give an answer without testing it which I don't really have time for at the moment. I would expect them to work similarly to matrices though. Certainly if I add or edit a field within a function I do not expect that field to be added or changed in the calling function's workspace.

Connectez-vous pour commenter.

Réponse acceptée

Robert Cumming
Robert Cumming le 17 Déc 2014
As I understand it when you store data in structs you are storing 2 things
1. The matrix/variable
2. The address of the memory/struct link (i.e. in.fieldA for example)
So when you change one field -> that field changes -> i.e. you create a new variable and the memory address changes. See this example below:
clc
clear
memory
a.one = zeros(10000,10000);
a.two = zeros(10000,10000);
b = a;
fprintf ( 2, 'b == a -> share same memory\n' );
memory
fprintf ( 2, '\n Now change one field only in b\n' );
b.two = ones(10000,10000);
whos
memory
When the two fields in a have been created we are using 1.6GB (the size of the var from whos and confirmed by the memory taken by matlab (from memory).
from whos b is also taking up 1.6GB -> but we know that they are the same physical memory location due to copy on write - as you stated.
Now when we change one of the fields in b we can check the increase in memory usage (in the above example by ~.8GB) and we see that the total memory usage increases only by the new single field in b (again by ~.8GB).
From this we can summise that in your example the fieldA in out will be created new (and take up new memory) but any other fields will retain the same memory location as the input variable in.

Plus de réponses (1)

Bill Tubbs
Bill Tubbs le 2 Mai 2021
Modifié(e) : Bill Tubbs le 2 Mai 2021
Seems that MATLAB makes a complete copy of a struct when it is passed to a function if any element is changed by the function (see demo script below). So is there no way to pass a reference to a struct to a function? From this article it would seem not.
s.a = 1;
s.b = 2;
s2 = change_struct(s);
assert(s.a == 1)
assert(s2.a == 2)
s.b = -1;
assert(s2.b == 2)
function s2 = change_struct(s)
s.a = s.a + 1;
s2 = s;
end

Catégories

En savoir plus sur Workspace Variables and MAT-Files dans Help Center et File Exchange

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by