Creating pointers for arrays

154 views (last 30 days)
Hau Kit Yong
Hau Kit Yong on 25 Apr 2019
Commented: Hau Kit Yong on 27 Apr 2019
I have a global array of values which will be operated on by a set of objects. Each of my objects operate on subsets of this global array by using its values and possibly changing them. I want these changes to be reflected in all instances of the array elements. For example, if globalArray(5:8) is referenced by objA.data(2:5) and objB.data(3:9), a change in objA.data(3) should automatically be reflected in globalArray(6) and objB.data(4). In Python, I would declare this array as a Numpy ndarray, and have my objects operate on its slices, as the slices are pointers/views into this array. In MATLAB, could this functionality be replicated by declaring this array as a global variable? Are there any differences between this implementation in the two languages?
I've looked at the accepted answer given here :https://uk.mathworks.com/matlabcentral/answers/109304-passing-matrix-using-call-by-reference but I don't see how I can take pointer slices as the actual array is still a value type.

Accepted Answer

James Tursa
James Tursa on 25 Apr 2019
Edited: James Tursa on 26 Apr 2019
First, there is no way in official MATLAB that I am aware of to do what you want to do. That is, you can't have variables that point into other variables and remain pointed no matter what you do to either variable. MATLAB's method of sharing variables in the background and copy-on-write mechanisms defeat this. In particular, global variables do not behave this way ... they follow the same sharing and copy-on-write mechanisms as other variables. Handle derived class variables can have this behavior, but only for the whole variable ... not for slices.
The only way to do exactly what you describe is with unofficial mex hacks into the variable, and doing this is VERY FRAGILE and can easily CRASH MATLAB if you are not very very careful. There is an FEX submission called SHAREDCHILD that can perform this hack, but I do not recommend it for your use because your code would be very fragile and users could easily do something perfectly legitimate at the MATLAB level that would end up crashing MATLAB. E.g.,
>> x = reshape(1:24,4,6)
x =
1 5 9 13 17 21
2 6 10 14 18 22
3 7 11 15 19 23
4 8 12 16 20 24
>> y = sharedchild(x,[1 2],[4 4],'ref') <-- y now points into x, but MATLAB doesn't know it
y =
5 9 13
6 10 14
7 11 15
8 12 16
>> y(:) = -y(:) <-- operations on the elements of y MUST be indexed
y =
-5 -9 -13
-6 -10 -14
-7 -11 -15
-8 -12 -16
>> x
x =
1 -5 -9 -13 17 21
2 -6 -10 -14 18 22
3 -7 -11 -15 19 23
4 -8 -12 -16 20 24
>> x(2:3,1:4) = 99
x =
1 -5 -9 -13 17 21
99 99 99 99 18 22
99 99 99 99 19 23
4 -8 -12 -16 20 24
>> y
y =
-5 -9 -13
99 99 99
99 99 99
-8 -12 -16
>> sharedchild(y,'unref') <-- to clean up the hack, you MUST 'unref' the variable first
>> y
y =
[] <-- 'unref' causes the link to be undone and the variable emptied safely
>> clear y <-- now you can safely clear the y variable
Since MATLAB didn't know that x and y are sharing memory (the SHAREDCHILD mex routine didn't tell it on purpose) the copy-on-write mechanism didn't kick in when x or y changed values. So, the above works but it is very fragile. Any action that causes MATLAB to deallocate the memory for one variable will invalidate the memory of the other, so any subsequent operation that accesses this memory will crash MATLAB. Doing any of the following while y is pointing into x will crash MATLAB:
  • Changing x in any way that causes a re-allocation
  • Changing y in any way that causes a re-allocation
  • Clearing x or y
E.g., the following simple acts would crash MATLAB since they cause the lhs to be re-allocated
y = -y
x = x + 1
Bottom line is you need to think of another way to get your desired behavior in MATLAB.
SHAREDCHILD can be found here (but I guarantee with 100% certainty that if you play around with the 'ref' capability you will crash MATLAB ... probably multiple times).
  1 Comment
Hau Kit Yong
Hau Kit Yong on 27 Apr 2019
Thanks for the answer. Eventhough it isn't exactly what I was looking for, I'll still accept it as an answer as it gave a very interesting alternative and was highly informative overall. For my implementation, I've decided to create a handle-type "Value" class with a single property containing a scalar value, which I then instantiate and put into an object array. This allows me to take reference slices of the array. It isn't the most elegant solution but this was what I decided to go with.

Sign in to comment.

More Answers (0)

Categories

Find more on Construct and Work with Object Arrays 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!