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""

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

malramsayAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

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
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?
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

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Angular Fundamentals

Learn the fundamentals of Angular 2, a JavaScript framework for developing dynamic single page applications.

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?
Sys_ProgCommented:
I do agree with u

I think SAFEARRAY's should be a better option
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



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
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C++

From novice to tech pro — start learning today.