My strategy here would be to:
A. run the program in a debugger, say GDB, to get a exhaustive
stacktrace for hints about where to look at.
B. have a quick look at the library directly (the "Use the Source Luke"
strategy).
Since I was curious about your problem (you had everything correct -
this should not fail), and have no access to your code, I checked out
the shapelib code from its cvs public repository and found out that the
last pointer, `double * padfMaxBound` is actually a pointer to an array
of 4 elements: in shapelib/shpopen.c: SHPGetInfo: starting line 823:
for( i = 0; i < 4; i++ )
{
if( padfMinBound != NULL )
padfMinBound[i] = psSHP->adBoundsMin[i];
if( padfMaxBound != NULL )
padfMaxBound[i] = psSHP->adBoundsMax[i];
}
This also explains why it does not segfault when you pass a null
pointer: no array out of bounds happen then.
padfMaxBound should point to a `double []` or `double [4]` instead of a
mere `double`.
I also ended checking the API documentation
(http://shapelib.maptools.org/shp_api.html) and they do document that
padfMinBound and padfMaxbound are pointers to 4 values X, Y, Z and M in
a four entry array.
You may want to check if there isn't any other of those "C tricks"
hiding in your D bindings.
On 12/07/2013 04:29 PM, Craig Dillabaugh wrote:
Hello,
I recently wrote bindings to the C-library Shapelib (it reads/writes a
common file format used in Geographic Information Systems).
I've been trying to write a small test program to make sure my bindings
'work' and I've come across a bizarre memory bug. I THINK I've
identified the code that causes the problem, but I have no idea why.
My test-suite includes this function:
void shapeRead(string filename) {
SHPHandle hShp = SHPOpen( std.string.toStringz( filename ), "rb" );
int n, shp_type;
double pad_min_bound, pad_max_bound;
SHPGetInfo( hShp, &n, &shp_type, &pad_min_bound, &pad_max_bound);
SHPClose( hShp );
}
If I comment out the SHPGetInfo call, then the segmentation fault
doesn't happen, but if its there then the program segfaults AFTER the
shapeRead function exits (eg. SHPClose runs fine) ).
In fact if I call SHPGetInfo as follows, the crash doesn't occur:
SHPGetInfo( hShp, &n, &shp_type, &pad_min_bound, null); //NULL pointer
last arg.
So in C the function SHPGetInfo is:
void SHPAPI_CALL
SHPGetInfo( SHPHandle hSHP, int * pnEntities, int * pnShapeType,
double * padfMinBound, double * padfMaxBound );
While my D binding is (pretty much the same):
extern( C ) void SHPGetInfo( SHPHandle hSHP, int* pnEntities,
int* pnShapeType, double* padfMinBound, double* padfMaxBound );
I have no idea what is going on. The sizes of ints and doubles are 4
and 8 bytes using gcc on my system (which is how I compiled my C
library) so those match the sizes of the corresponding D types [I
thought maybe there was a type-size mismatch and that was causing
something to be overwritten, but it doesn't appear that way].
Any hints on where to look next would be appreciated.
Craig