heap corruption when using C library

General FreeBASIC programming questions.
Post Reply
srvaldez
Posts: 3390
Joined: Sep 25, 2005 21:54

heap corruption when using C library

Post by srvaldez »

I re-wrote my decimal MP math routines in C and it seems to work ok except that I get a heap corruption (error -1073740940 or 0xC0000374) when using shared variables in FB -- for arrays using redim works ok but you can't use redim for non-array variables

Code: Select all

Dim Shared As Decfloat x
will cause a heap corruption
the C code for the DecFloat structure and it's initialize function are

Code: Select all

typedef struct {
	int32_t sign;
	uint32_t exponent;
	uint32_t* mantissa;
}
DecFloat_struct;

void DecFloat_init(DecFloat_struct* df) {
	df->sign = 0;
	df->exponent = 0;
	df->mantissa = calloc((NUM_DWORDS + 1 + EXTRAWORDS), 4);
	if (df->mantissa == NULL) {
		printf("Error! memory not allocated.");
		exit(4);
	}
}
why does the heap get corrupted with shared variables in FB?
I have no problem if using libmpfr for example
you can get the source code and a compiled 64-bit lib from https://github.com/srvaldez/BigFloat/tr ... /DecFloatC
fxm
Moderator
Posts: 12181
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: heap corruption when using C library

Post by fxm »

I wonder if the constructor of a shared static object can call a procedure in a library.

Jeff ?
SARG
Posts: 1785
Joined: May 27, 2005 7:15
Location: FRANCE

Re: heap corruption when using C library

Post by SARG »

srvaldez wrote: Feb 07, 2024 9:59 you can't use redim for non-array variables
I suppose that you want to say something else as redim is to be used with arrays.

Not sure it's important : in bi file there is 'as long exponent' but in C file 'uint32_t exponent'
srvaldez
Posts: 3390
Joined: Sep 25, 2005 21:54

Re: heap corruption when using C library

Post by srvaldez »

@SARG
I changed the exponent in the bi to long because the following didn't work as expected in 32-bit

Code: Select all

if z1.DecNum.exponent<>0 then
	t=(z1.DecNum.exponent And &h7FFFFFFF)-BIAS-1
else
	t=0
endif
thanks guy for looking into the problem :D
srvaldez
Posts: 3390
Joined: Sep 25, 2005 21:54

Re: heap corruption when using C library

Post by srvaldez »

I found the culprit

Code: Select all

Operator Decfloat.let ( Byref rhs As Decfloat )
	this.DecNum.sign=rhs.DecNum.sign
	this.DecNum.exponent=rhs.DecNum.exponent
	memcpy( this.DecNum.mantissa, rhs.DecNum.mantissa, NUM_BYTES )
End Operator
changing it to the following and all is well, need to make sure and replace all memcpy
there's still a problem

Code: Select all

Operator Decfloat.let ( Byref rhs As Decfloat )
	this.DecNum.sign=rhs.DecNum.sign
	this.DecNum.exponent=rhs.DecNum.exponent
	for i as long=0 to NUM_DWORDS
		this.DecNum.mantissa[i]=rhs.DecNum.mantissa[i]
	next
End Operator
SARG
Posts: 1785
Joined: May 27, 2005 7:15
Location: FRANCE

Re: heap corruption when using C library

Post by SARG »

Is it correct for testing to use this :

Code: Select all

#include "DecFloatC.bi"
Dim Shared As Decfloat x
print "end"
If yes, there is an access violation that seems arises with the address of NUM_DWORDS

Code: Select all

Constructor Decfloat ( )
	si2fp(this.DecNum, 0, NUM_DWORDS)
End Constructor

Not related but why this test with same statement in both branches

Code: Select all

Constructor Decfloat ( Byval rhs As Integer )
	#ifdef __FB_64BIT__
		si2fp(this.DecNum, rhs, NUM_DWORDS )
	#else
		si2fp(this.DecNum, rhs, NUM_DWORDS )
	#endif
End Constructor
fxm
Moderator
Posts: 12181
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: heap corruption when using C library

Post by fxm »

In order to test the behavior with a simple dynamic variable, can you try this principle:

Code: Select all

Dim Shared Byref As Decfloat x = *Cptr(Decfloat Ptr, 0)
@x = New Decfloat
.....
.....
.....
Delete @x
srvaldez
Posts: 3390
Joined: Sep 25, 2005 21:54

Re: heap corruption when using C library

Post by srvaldez »

@SARG
it looks like a terrible blunder on my part :oops:
NUM_DWORDS is set when when DecFloat_Set_Digits is called but apparently the overloaded functions/operators are set when NUM_DWORDS hasn't been defined yet
I will have rethink the whole thing
srvaldez
Posts: 3390
Joined: Sep 25, 2005 21:54

Re: heap corruption when using C library

Post by srvaldez »

I wanted to be able to set the precision at runtime, that's why I went this route
what puzzles me is why the following doesn't help

Code: Select all

const digits_precision = 128

dim shared as long NUMBER_OF_DIGITS, NUM_DIGITS, NUM_DWORDS, NUM_BYTES

scope
	dim as long  n = digits_precision / 8
	if (8 * n) = digits_precision then
		NUMBER_OF_DIGITS = digits_precision
	else
		NUMBER_OF_DIGITS = 8 * (n + 1)
	end if
	NUM_DIGITS = NUMBER_OF_DIGITS
	NUM_DWORDS = NUMBER_OF_DIGITS / 8
	NUM_BYTES = 4 * (NUM_DWORDS)
end scope
#Include "DecFloatC.bi"
I commented-out the extern NUM_DWORDS and so on
srvaldez
Posts: 3390
Joined: Sep 25, 2005 21:54

Re: heap corruption when using C library

Post by srvaldez »

in the file DecFloatC.c I edited
int NUMBER_OF_DIGITS=64;
int NUM_DIGITS=64;
int NUM_DIGITS2;
int NUM_DWORDS=8;
int NUM_BYTES=32;
int EXTRAWORDS = 0;
and put the following in the DecFloat_init function

Code: Select all

	printf("NUM_DWORDS + 1 + EXTRAWORDS=%d\n", NUM_DWORDS + 1 + EXTRAWORDS);
and run this FB code

Code: Select all

dim shared as long NUMBER_OF_DIGITS, NUM_DIGITS, NUM_DWORDS, NUM_BYTES

scope
	dim as long  n = digits_precision / 8
	if (8 * n) = digits_precision then
		NUMBER_OF_DIGITS = digits_precision
	else
		NUMBER_OF_DIGITS = 8 * (n + 1)
	end if
	NUM_DIGITS = NUMBER_OF_DIGITS
	NUM_DWORDS = NUMBER_OF_DIGITS / 8
	NUM_BYTES = 4 * (NUM_DWORDS)
end scope
#Include "DecFloatC.bi"

DecFloat_Set_Digits(digits_precision, 0)
Const order=4
print "order = ";order
Dim As Decfloat z1, z2

Dim Shared As Decfloat roots(order)
and the printout was

Code: Select all

NUM_DWORDS + 1 + EXTRAWORDS=9
NUM_DWORDS + 1 + EXTRAWORDS=9
NUM_DWORDS + 1 + EXTRAWORDS=9
NUM_DWORDS + 1 + EXTRAWORDS=9
NUM_DWORDS + 1 + EXTRAWORDS=9
order =  4
NUM_DWORDS + 1 + EXTRAWORDS=17
NUM_DWORDS + 1 + EXTRAWORDS=17
notice that Dim Shared As Decfloat roots(order) is executed first and then

DecFloat_Set_Digits(digits_precision, 0)
Const order=4
print "order = ";order
Dim As Decfloat z1, z2

with redim or without shared the order of execution is normal
looks to me that my C code and the bi were OK, but it can't function with shared arrays without using redim
srvaldez
Posts: 3390
Joined: Sep 25, 2005 21:54

Re: heap corruption when using C library

Post by srvaldez »

I changed my code, instead of a function to set the precision I changed the initializer to take a precision argument, the FB code needs to start with these 2 lines

Code: Select all

const dec_float_digits_precision = 64
#Include "DecFloatC.bi"
there are no problems with shared variables :D
never knew that FB would execute code out-of-order until today :o
fxm
Moderator
Posts: 12181
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: heap corruption when using C library

Post by fxm »

This topic might interest you:
Executables and Compiling
Post Reply