How are structs handled when passed to a function?
9 ビュー (過去 30 日間)
古いコメントを表示
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 件のコメント
Adam
2014 年 12 月 17 日
編集済み: Adam
2014 年 12 月 17 日
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.
採用された回答
Robert Cumming
2014 年 12 月 17 日
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.
0 件のコメント
その他の回答 (1 件)
Bill Tubbs
2021 年 5 月 2 日
編集済み: Bill Tubbs
2021 年 5 月 2 日
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
0 件のコメント
参考
カテゴリ
Help Center および File Exchange で Workspace Variables and MAT-Files についてさらに検索
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!