Go Premium for a chance to win a PS4. Enter to Win

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 242
  • Last Modified:

MultiDimArrays - What's wrong with my code?

Hi,

Is there anything wrong with this C++ code?  If not, does anyone have any idea why I'm getting the memory error message below?

**********************************

__declspec(dllexport) double __stdcall STCDO3(double ** sigma, int rowssigma)
{
   return sigma[0][0];
}

**********************************

I'm trying to call this C++ dll function from an excel VBA like this,

**********************************

Private Declare Function STCDO3 Lib "STCDO_C.DLL" _
(sigma As Double, ByVal rowssigma As Integer) As Double

Function STC() As Double
   
    Dim arrsigma(7, 1) As Double
    Dim k As Integer
    Dim l As Integer
    k = 10
    l = 20
   
    For i = 0 To 7
        arrsigma(i, 0) = k * i
        arrsigma(i, 1) = l * i
    Next
   
    STC = STCDO3(arrsigma(0, 0), 7)
   
End Function

**********************************

and when I do I get the error mesesage,

"The instruction at "0x03d915dd" referenced memory at "0x00000000". The memory could not be "read""

**********************************

0
malramsay
Asked:
malramsay
  • 3
  • 2
  • 2
1 Solution
 
Sys_ProgCommented:
Hi

I think the call to the function is incorrect

STC = STCDO3(arrsigma(0, 0), 7)


Yoiu are passing the first element of the two dim array [i.e. a double value] while in C++, the function is expecting a pointre to a pointer to a double

Amit
0
 
malramsayAuthor Commented:
Hi Amit,

This microsoft page deal with this, but it's only concerning one dimensional arrays.  

http://support.microsoft.com/default.aspx?scid=http://support.microsoft.com:80/support/kb/articles/Q207/9/31.asp&NoWebContent=1&NoWebContent=1

//So, the C++ function starts like,

long __declspec (dllexport) __stdcall AddLongs_Pointer(long *plArrayOfLongs, long lElements)   {

//Whilst the VBA is

Private Declare Function AddLongs_Pointer Lib "MyStDll.dll" _
   (FirstElement As Long, ByVal lElements As Long) As Long

lSum = AddLongs_Pointer(ArrayOfLongs(0), UBound(ArrayOfLongs)+1)

//Is my C++ correct in how it is receiving the multidimarray (i.e. with **)?  If you were passing a multidimarray from another C++ function to that one, is that how you would receive and then use it?
0
 
Sys_ProgCommented:
No man

it should be something like this

#include <iostream>

using namespace std ;

int f ( int p[][5] ) {
   return p[0][0] ;
}
int main ( ) {
   int a[5][5] ;
   a[0][0] = 1 ;
   cout << f ( a ) ;
   system ( "PAUSE" ) ;
}


i.e. For one dim array, u can use a pointer notation
But for more than one dim, u should use the array notation and that u will have to provide all the dimensions except the first one

Amit
0
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

 
malramsayAuthor Commented:

Oh dear.  I am going to also be sending to this C++ function multidimensional arrays that can be any number of rows by any number of columns.  I understood that when single arrays are passed between functions you have to send the size of the array as a separate variable, so the function knew the size of the array.  

I was hoping to thus send a multidimensional array with two variables - one for the rows and one for the columns.  I suppose this is not possible?  

I think I'm going to have to use SAFEARRAYS, which I really didn't want to do as they look rather complicated and I'm running out of time.  Are there any other alternatives you know about?
0
 
Sys_ProgCommented:
I do agree with u

I think SAFEARRAY's should be a better option
0
 
itsmeandnobodyelseCommented:
Look at this:

template <class T>
class Array2D
{
private:
    T*    data;
      int   dimy;
      int   dimx;

public:
    Array2D(T* d, int y, int x = -1)
         : data(d), dimy(y), dimx(x)      {}
    Array2D(T** d, int y, int x = -1)
         : data(d[0]), dimy(y), dimx(x)      {}
      T& operator() (int y, int x) {       int pos = (y * dimy + x); return data[pos]; }
      
};
                                     
void main()
{
      int   arr[3][4] = {  { 1, 2, 3, 4, }, { 1, 2, 3, 4, }, { 1, 2, 3, 4, }, };
      Array2D<int>  ia((int*)arr, 3);
      ia(3, 4) = ia(2, 5);
}

For your example it would be

__declspec(dllexport) double __stdcall STCDO3(double ** sigma, int rowssigma)
{
   Array2D<double> s(sigma, rowssigma);
   return s(0, 0);
}

Easier than SAFE_ARRAY ?

Regards, Alex



0
 
itsmeandnobodyelseCommented:
Forget the line

        ia(3, 4) = ia(2, 5);       // kaboom!!

Better

         ia(0, 1) = ia(2, 2);

I reduced the dimensions for the example. :-)

Alex
0

Featured Post

VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

  • 3
  • 2
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now