LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

3DGraph memory

Hi,
I try to make an application with an 3dGraph ActiveX element and I've problems with converting the allocated memory:
I have somewhere a structure "mono"
 
typedef struct
{
...
double ** spectrum;
...
}mono;
 
...
Then I allocate memory for it:
In this example mono.angles=2 and mono.datasize=6
 //first one dimension pointers
   mono.spectrum = (double**) malloc(mono.angles*sizeof(double*));
//then the others

   for(iy=0;iy<mono.angles;iy++)
   {
      mono.spectrum[iy] = (double*)malloc(mono.datapoints*sizeof(double)); 
   }
Here I have allocated 6x2x8 = 96 Bytes, haven't I ?????
...
Then data is filled into the 2d array. This works!
...
But the next call makes problems:
    CA_VariantSet2DArray (&vArray, CAVT_DOUBLE|CAVT_ARRAY,mono.angles, mono.datapoints, &mono.spectrum[0][0]);
The error I get is the following:
 FATAL RUN-TIME ERROR:   "callbacks.c", line 172, col 97, thread id 0x00000904:   Array argument too small (48 bytes).  Argument must contain at least 96 bytes (96 elements).
//next: Plot it
   CW3DGraphLib_CWPlot3DPlot3DSimpleSurface (plotHandle, NULL, vArray,CA_DEFAULT_VAL);
Can anybody help???
0 Kudos
Message 1 of 5
(3,839 Views)
Your second malloc() allocates 48 (6*8) in each of two loops (assuming that mono.datapoints is what you meant to type when you wrote mono.datasize). So yes, you have allocated 96 bytes overall but you have no right to assume that the second 48 byte allocation is contiguous with the first - the system is quite at liberty to place this memory anywhere it chooses. Hence the error - as far as the debug system is concerned there are only 48 bytes at the address specified, because that's what you asked for.
 
JR
0 Kudos
Message 2 of 5
(3,834 Views)

Hi and thank you.

that's it.

now I make it this way:

   double * spectrum=(double*)malloc(mono.angles*mono.datapoints*sizeof(double));
   mono.spectrum = &spectrum;

0 Kudos
Message 3 of 5
(3,831 Views)
I thougth my problems are gone but I have still problems:
 
I allocated the memory like this:
anzX=3, anzY=5
 pZ = (double*)malloc( anzX * anzY * sizeof(double) );
 pX = (double*)malloc( anzX * sizeof(double) );
 pY = (double*)malloc( anzY * sizeof(double) );  
 ppZ = &pZ;              
...
//when I try to plot the data is wrong 
CA_VariantSet1DArray(&xVt, CAVT_DOUBLE, anzX, pX);
CA_VariantSet1DArray(&yVt, CAVT_DOUBLE, anzY, pY);
CA_VariantSet2DArray (&zVt, CAVT_DOUBLE, anzX, anzY, ppZ);
CW3DGraphLib_CWPlot3DPlot3DSurface(plotHandle,NULL,xVt,yVt,zVt,CA_DEFAULT_VAL);
 
So I made some tests with the array:
If I access the array like this:
ppZ[0][0] = 1.;  //is correct
ppZ[0][4] = 5.;                //still correct
ppZ[1][0] = 6;           //Error during runtime
 
the memory is allocated on the positions ppZ[0][0] to ppZ[0][14] , so I can not acces like an 2dim array.
So I have 2 questions:
1.)How can I work with the pointer to pointer and access the data as a 2 dim Array with the brackets ppZ[x][y]?
When I make it like in my first entry, the data is not in series in the memory. But I want it in series!
 
2.)The 3dGraph only works with a "double test[3][5];" definition but not with the pointer to pointer.
How can I allocate the memory dynamically and use this with CW3dGraph?
Can anybody help?
 
  
0 Kudos
Message 4 of 5
(3,805 Views)

In situations like this it can often help to use a typedef to clarify what is intended, for example by defining a 1D array type. If you then have a pointer to an object of this type, it will naturally beome a 2D array and the compiler should be happy. One drawback (of the C89 CVI compiler) may be that the size of such a typedef'ed array has to be fixed at compile time, so this could compromise your overall approach of dynamic allocation/sizing. (I don't have access to my CVI compiler at the moment so I can't test this.)

JR

Message 5 of 5
(3,797 Views)