Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

static 2D array declaration

Status
Not open for further replies.

maria7

Programmer
Dec 11, 2002
3
BE
I have a problem declaring a static 2D array, because the parameters that I use to size it are passed from a Fortran function (they must come from there). Therefore, they are not recongnized as constant numbers. Is there any way around that?
 
why 2D ?
i suppose you get from fortran a MAX int||long value
try it dynamically using malloc && realloc on a pointer
of the type you will use. -----------
when they don't ask you anymore, where they are come from, and they don't tell you anymore, where they go ... you'r getting older !
 
The reason for 2D is because it is a geometry file, so it has to be 2D. I've had problems passing a 2D array from Fortran to C, so I copied a 2D array into 1D and passed it to C that way, but I can't copy it back into 2D (it's a necessary part of the program).... I am sorry, I didn't really understand what you said, I am not a good programmer (actually, an engineer)....
 
I'd guess the reason you have problems passing the array is that FORTRAN stores 2D arrays in column-major order, while C et. al. store them in row-major order. That 1D array is probably the best way around that particular problem.

I'd go with jamisar's suggestion to use dynamic memory allocation. You use the malloc (memory allocation) function to get the amount of memory you need at run time.

For example, you if you want to copy a 4 x 4 array of ints, you'd allocate enough space for 4 pointers to int:

[tt]int **grid = malloc( 4, sizeof( int * ) );[/tt]

Then you'd go through the array of pointers and similarly allocate space for 4 ints in each of those.

After you're done with the array, go through and free everything you dynamically allocated by using the free function.
 
Can't you cast the resulting values of
your fortran function to type int?

Either that or pass a pointer to the fortran function and create a conversion
wrapper for it?

Could we see the problem portion of code?


 
you can use an array of (n,n) dimensions like a unidimensional array (or pointer)if you use pseudoindices, considering that an array ocuppies adyacent positions in memory, according fortran convention.
If i see the source i could help you
 
This is a subroutine to get inverse of a matrix, passing an array form visual basic, it was in fortran. if i do not understand you have a problem like this. i think it can help you.

#include <windows.h>
#include <math.h>

void __stdcall matinv( int n, double *a_, double *ai_);

BOOL WINAPI DllMain( HINSTANCE hinstDLL ,DWORD dwReason ,LPVOID lpReserved )
{
// Perform actions based on the reason for calling.
switch( dwReason )
{
case DLL_PROCESS_ATTACH:
// Initialize once for each new process.
// Return FALSE to fail DLL load.
break;

case DLL_THREAD_ATTACH:
// Do thread-specific initialization.
break;

case DLL_THREAD_DETACH:
// Do thread-specific cleanup.
break;

case DLL_PROCESS_DETACH:
// Perform any necessary cleanup.
break;
}
return TRUE;
}


void __stdcall matinv( int n, double *a_, double *ai_)
{
double *a=(double *)a_ /* [n*n] elements */;
double *ai=(double *)ai_ /* [n*n] elements */;
int i,j,k;
double t,ti;

#define aind(i1,i2) (((i2)-1)*n+(i1)-1)
#define aiind(i1,i2) (((i2)-1)*n+(i1)-1)

for (i=1;i<=n;i++)
{
for (j=1;j<=n;j++)
{
if (i == j) ai[aiind(i,j)]=1;
else
{
ai[aiind(i,j)]=0;
}
}
}
for (i=1;i<=n;i++)
{
for (j=i+1;j<=n;j++)
{
if (abs(a[aind(j,i)]) > abs(a[aind(i,i)]))
{
for (k=1;k<=n;k++)
{
t=a[aind(i,k)];
ti=ai[aiind(i,k)];
a[aind(i,k)]=a[aind(j,k)];
ai[aiind(i,k)]=ai[aiind(j,k)];
a[aind(j,k)]=t;
ai[aiind(j,k)]=ti;
}
}
}
t=a[aind(i,i)];
for (k=1;k<=n;k++)
{
a[aind(i,k)]=a[aind(i,k)]/t;
ai[aiind(i,k)]=ai[aiind(i,k)]/t;
}
for (j=1;j<=n;j++)
{
if (i != j)
{
t=a[aind(j,i)];
for (k=1;k<=n;k++)
{
a[aind(j,k)]=a[aind(j,k)]-(t*a[aind(i,k)]);
ai[aiind(j,k)]=ai[aiind(j,k)]-(t*ai[aiind(i,k)]);
}
}
}
}
}

 
You could always declare it as a 1D array and access it as a 2D array. For instance, if it requires a rmax x cmax array

int* C2F = (int*) malloc (rmax * cmax * sizeof (int));

This makes sure the cells are contiguous, which is what Fortan wants. Pass C2F to the Fortran routine. Fortran doesn't know about C type 2D arrays.

When you are accessing it in C, put on an additional layer.

#define cell(r,c) C2F[r*cmax+c]

This is similar to the technique used by bytebit. It is far easier than two lots of [][]. There is no end of problems using dynamic 2D arrays in C because routines only expect one dimension to be dynamic.

 
it's a good idea but it's better using ForPasc that translate from fortran to c, pascal and c++
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top