Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Explicitly setting the value of a pointer

I am writing a mex-file (using C++) that will accept a memory address as an input, and operate on data at that memory address. Because I am forced to use MATLAB as my environment, my program can only accept MATLAB data types as inputs (char, bool, float, double, and int). How can I go about assigning my input value to a pointer?

Pseudocode:

// Outside of program
// double input_arg = hex2dec('00C2E4E8')

double *pointer;
pointer = (double *)input_arg;
// pointer == hex2dec('00C2E4E8')

Basically, this can be seen as me hardcoding the value of a pointer similar to:

double *pointer = (double *)hex2dec('00C2E4E8');

I am receiving the error:

error C2440: '=' : cannot convert from 'double' to 'double *'

I have also tried using static/const/reinterpret/dynamic_cast, but I don't really understand how they work (and I couldn't get them to work). Is it possible at all to manually assign memory address values to pointers?

like image 555
Brian Avatar asked Aug 08 '11 17:08

Brian


People also ask

How do I change the value of a pointer?

To update the value of a variable via pointer we have to first get the address of the variable and then set the new value in that memory address. We get the address via address of & operator and then we set the value using the value at the address of * operator.

What is the default value of a pointer?

1. The default value or zero-value of a pointer is always nil. Or you can say that an uninitialized pointer will always have a nil value.

What is the value about pointer?

A pointer is a variable that points to another variable. This means that a pointer holds the memory address of another variable. Put another way, the pointer does not hold a value in the traditional sense; instead, it holds the address of another variable.


2 Answers

It seems that you cannot use a double, which is a floating point type, as a representation of an address in memory, which is inherently an integer value.

I guess that your input_arg should be defined as a MATLAB int type, not as a double.

like image 129
sergio Avatar answered Sep 28 '22 04:09

sergio


What you're trying to do is dangerous because you're passing raw pointers to some C++ code, making assumptions about what exists at that location and executing code based on those assumptions. But let's say you've taken care of all those security issues.

You probably want to pass the pointer to your MEX file as a UINT64 (so that the code can be recompiled and used as is on a 64-bit installation of MATLAB).

On the MATLAB side:

ptrArg = uint64(hex2dec( '00C2E4E8' ));
myMexFile( ptrArg );

Within your mex function:

void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
  if( nrhs < 1 ) {
    // error

  } else {
    // Verify that the address argument is a UINT64 
    if( mxGetClassID( prhs[0] ) != mxUINT64_CLASS ) {
      // error

    }
  }

  // Done with error checking, now perform the cast
  uint64_T mlData = *static_cast<unsigned long long *>( mxGetData( prhs[0] ) );
  double *p = reinterpret_cast<double *>( mlData );

  // Do whatever with p
}

Note: You can do the same with a double as well, just change the mxGetClassID check to look for mxDOUBLE_CLASS. In this case the cast expression becomes:

double *p = reinterpret_cast<double *>( *mxGetPr( prhs[0] ) );

EDIT:
What I've said about being about to get this code to work on a 32 or 64-bit machine is only true if both machines are little endian. Otherwise, if you pass a 32-bit pointer in a 64-bit uint on a big-endian machine and cast it to a double * you'll get a pointer that is 0x00000000.

You can handle the endianness issues by using the MATLAB function computer to detect machine endianness. If byte swapping is needed you can use swapbytes. To execute these functions from your C++ code use mexCallMATLABWithTrap.

like image 34
Praetorian Avatar answered Sep 28 '22 05:09

Praetorian