mxgetpr different variable same pointer

Hello,
Immediately before the call to a mex function some variables are copied into another variable and both copies are passed to the mex function. However, mxGetPr returns the same address for both copies of the variable. I would have thought that when copied to a new variable the data should have been duplicated at a second address and so mxGetPr would return different pointer. Is this not the case? And if not how can I pass two independent copies of some data to a mex function?
Thanks,
Jamie

Answers (2)

When you do a simple assignment at the MATLAB level like this:
B = A;
MATLAB will create B as a shared data copy of A. I.e., both B and A will point to the same data area. You have discovered this with your mxGetPr addresses being the same. You can also see this easily with small variables by using format debug:
format debug
A = 1:3
B = A
The data will not get duplicated until a change is made to one of the elements, forcing a data copy. E.g.,
format debug
A = 1:3
B = A
B(1) = 5
You will now see that the pr pointers are different. This is all normal and natural behavior for MATLAB.
Why do you think you need two deep copies of the same data passed into your mex function? Are you trying to modify the data in place? Or ...?
JM18
JM18 on 25 Sep 2017
I used a workaround by adding and subtracting 1 from the variables that shared a work area to force Matlab to create two independent copies.
I am migrating code from a legacy system to Matlab and this legacy code calls a C++ function passing 92 parameters all as double pointers. Some are arrays and some unidimensional variables. The C++ code is thousands of lines so I don't want to get into modifying it at the moment. The mex function that acts as glue code pretty much just pass the pointers retrieved with mxGetPr on to the original C++ function. If anyone has a better alternatives that doesn't involve altering original C++ code I would be very interested.
That Matlab creates a shared data copy pointing to the same area after assignment seems like a sensible use of memory, but that it pass on a single pointer to another environment that doesn't know that these should be distinct data objects seems faulty. Maybe there are some other mex function that I haven't explored that would solve this for me but at the moment, apart from the ugly workaround, I don't see how to pass on a unique pointer for each parameter.
Thanks,
Jamie.

3 Comments

James Tursa
James Tursa on 25 Sep 2017
Edited: James Tursa on 25 Sep 2017
"... adding and subtracting 1 from the variables ..."
Just adding 0 to one element does the trick on my system. No need to change every element of the variable.
"... Some are arrays and some unidimensional variables ..."
Realize that MATLAB stores arrays in column order in memory, whereas C/C++ stores them row order in memory. So if you are passing a mxGetPr pointer from a 2D matrix into a C/C++ routine that is using it as a regular 2D array, you will have problems if you don't account for that difference.
"... The mex function that acts as glue code pretty much just pass the pointers retrieved with mxGetPr on to the original C++ function ..."
So, you still haven't explained why you think it is a problem passing identical data pointers to your C++ function. Unless you are modifying the data in place, (which you shouldn't be doing at the risk of screwing up your MATLAB workspace), there should be no problem passing identical pointers. Are you attaching the pointers to C++ class objects or something like that? Since those mxGetPr pointers should be treated as read-only data, there should be nothing that you are doing with them in your C++ function that should complain if some of them are identical. If there is something that you are doing in that C++ function that requires the pointers to be different, my guess is you are doing something invalid to the data and you are risking screwing up your MATLAB workspace.
Yes the on-bound original C++ function edits some of the inputs. I want the variables values changed in the Matlab workspace so what is the issue with editing inplace? Why should mxGetPr pointers be treated as read only?
Because you, the programmer, are not given any official functions in the API to determine if a passed in variable is sharing data with another variable. You happen to know it in your particular case because you checked their data pointers and they were the same. All well and good ... but how do you know that there isn't a third variable out there in your workspace that is sharing data with your first variable? And that is the key to this whole issue ... you don't ... at least not at the official API level.
To my knowledge, there are generally four ways that variables can be sharing data with other variables:
1) Shared data copy (the pr pointers are the same)
2) Shared reference copy (multiple entries are the same in a cell or struct array)
3) Shared parent copy (similar to shared reference copy but sharing is through parent)
4) Shared handle variable (special classdef case)
Problem is, there are NO API functions that can tell you any of this. You can sometimes (as you have found out) tell by comparing pr pointers of variables you suspect may be sharing data. But it is very difficult, and in some cases close to impossible, to detect the sharing status of a variable just by examining it with official API functions. Even hacking into the innards of the variable will not necessarily reveal all of the background sharing that might be going on.
So, where does that leave you? If you are going to (against the official rules) modify a prhs[ ] variable in place in a mex routine, you must be very careful at the caller level (i.e., in your m-code) that you DO NOT DO ANYTHING THAT WILL CAUSE SHARING TO TAKE PLACE! That means you should be creating these variables from scratch to make sure they are not shared copies of something else, or take steps to make them unshared prior to calling your mex routine. And then don't do things like simple assignments, or reshapes, etc. If you can scrub your code of all the stuff that might cause problems, then yes you can get away with modifying prhs[ ] variables in place safely. But it is tricky and you have to be very careful ... otherwise you will unintentionally change all of the other variables in your workspace that happen to be sharing data with your modified variables.

Sign in to comment.

Tags

Asked:

on 24 Sep 2017

Commented:

on 26 Sep 2017

Community Treasure Hunt

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

Start Hunting!