I'm new programing in C. I have a main code with 781 lines that is out of control because garbage value is stored in vectors. A short part of the main code is shown below where it calls a subroutine called diff_conv_intermedia1.
diff_conv_intermedia1(&factorteta,&N,ID,DIFF,X1_intermedia,Y1_intermedia,X1C_intermedia,Y1C_intermedia,CU1_intermedia,CV1_intermedia,AW1_intermedia,AE1_intermedia,AS1_intermedia,AN1_intermedia,AP1_intermedia,Q1_intermedia,FXI1,FYI1,FI_intermedia1,1,2,1,1);
int q,w;
for(q=1;q<(*factorteta_Ptr)*2+1;q++)
{
for(w=1;w<(*N_Ptr)+1;w++)
{
printf("%lf\n",AP1_intermedia[q][w]);
}
}
So the subroutine shown below. When I print the results inside the subroutine, everything is OK, but when I print the results outside the subroutine, in the main code, garbage is stored in the vectors as AP1_intermedia. I don't know what could be wrong. I repeat the same procedure with other subroutines and I don't have any errors.
int diff_conv_intermedia1(int *factorteta_Ptr,
int *N_Ptr,
int ID,
double DIFF,
double X[(*factorteta_Ptr)*2+1][*N_Ptr+1],
double Y[(*factorteta_Ptr)*2+1][*N_Ptr+1],
double XC[(*factorteta_Ptr)*2+2][*N_Ptr+2],
double YC[(*factorteta_Ptr)*2+2][*N_Ptr+2],
double CU[(*factorteta_Ptr)*2+1][*N_Ptr+1],
double CV[(*factorteta_Ptr)*2+1][*N_Ptr+1],
double AW[(*factorteta_Ptr)*2+1][*N_Ptr+1],
double AE[(*factorteta_Ptr)*2+1][*N_Ptr+1],
double AS[(*factorteta_Ptr)*2+1][*N_Ptr+1],
double AN[(*factorteta_Ptr)*2+1][*N_Ptr+1],
double AP[(*factorteta_Ptr)*2+1][*N_Ptr+1],
double Q[(*factorteta_Ptr)*2+1][*N_Ptr+1],
double FX[(*factorteta_Ptr)*2+1][*N_Ptr+1],
double FY[(*factorteta_Ptr)*2+1][*N_Ptr+1],
double FI[(*factorteta_Ptr)*2+1][*N_Ptr+1],
int WBC,int EBC,int SBC,int NBC)
{
int i,j;
double value,* valuePtr;
double AED, AWD, AND, ASD;
double AEC, AWC, ANC, ASC;
valuePtr = &value;
// Diffusive coefficients
for(i=1;i<(*factorteta_Ptr)*2+1;i++)
{
for(j=1;j<*N_Ptr+1;j++)
{
AWD = -DIFF*(Y[i][j-1]-Y[i-1][j-1])/(XC[i][j]-XC[i][j-1]);
AED = -DIFF*(Y[i][j]-Y[i-1][j])/(XC[i][j+1]-XC[i][j]);
AND = -DIFF*(X[i][j]-X[i][j-1])/(YC[i+1][j]-YC[i][j]);
ASD = -DIFF*(X[i-1][j]-X[i-1][j-1])/(YC[i][j]-YC[i-1][j]);
// Convection term
if(ID==2)
{
max1_or_min2(CU[i][j-1],1,&value);
AWC=-*valuePtr;
max1_or_min2(CU[i][j],2,&value);
AEC=*valuePtr;
max1_or_min2(CV[i-1][j],1,&value);
ASC=-*valuePtr;
max1_or_min2(CV[i][j],2,&value);
ANC=*valuePtr;
}
if(ID==1)
{
AWC =-CU[i][j-1]*(1.0-FX[i][j-1]);
AEC =CU[i][j]*FX[i][j];
ASC =-CV[i-1][j]*(1.0-FY[i-1][j]);
ANC =CV[i][j]*FY[i][j];
}
// Set Coefficients matrix
AW[i][j] = AWD+AWC;
AE[i][j] = AED+AEC;
AS[i][j] = ASD+ASC;
AN[i][j] = AND+ANC;
AP[i][j] = -(AE[i][j]+AW[i][j]+AN[i][j]+AS[i][j]);
Q[i][j] = 0.0;
}
}
// West Boundary - Inlet B.C
for(i=1;i<(*factorteta_Ptr)*2+1;i++)
{
if(WBC==1) Q[i][1] = Q[i][1]-AW[i][1]*FI[i][0];
if(WBC==2) AP[i][1] = AP[i][1] + AW[i][1];
AW[i][1] = 0.0;
// East Boundary - (1)Dirichlet (2)ZERP-GRAD Outflow B.C
if(EBC==1) Q[i][*N_Ptr] = Q[i][*N_Ptr] - AE[i][*N_Ptr]*FI[i][*N_Ptr+1];
if(EBC==2) AP[i][*N_Ptr] = AP[i][*N_Ptr] + AE[i][*N_Ptr];
AE[i][*N_Ptr] = 0.0;
}
// South Boundary - (1)Dirichlet (2)ZERO-GRAD
for(j=1;j<*N_Ptr+1;j++)
{
if(SBC==1) Q[1][j] = Q[1][j] - AS[1][j]*FI[0][j];
if(SBC==2) AP[1][j] = AP[1][j] + AS[1][j];
AS[1][j] = 0.0;
// North Boundary - (1)Dirichlet (2)ZERO-GRAD
if(NBC==1) Q[(*factorteta_Ptr)*2][j] = Q[(*factorteta_Ptr)*2][j] - AN[(*factorteta_Ptr)*2][j]*FI[(*factorteta_Ptr)*2+1][j];
if(NBC==2) AP[(*factorteta_Ptr)*2][j] = AP[(*factorteta_Ptr)*2][j] + AN[(*factorteta_Ptr)*2][j];
AN[(*factorteta_Ptr)*2][j] = 0.0;
}
// Print
int l,k;
for(l=1;l<(*factorteta_Ptr)*2+1;l++)
{
for(k=1;k<*N_Ptr+1;k++)
{
printf("%lf %lf %lf %lf\n",AP[l][k],AS[l][k],AN[l][k],FI[l][k]);
}
}
return 0;
}
If anybody wants I can send all code, but have many extensions.
In your function declaration:
double AP[(*factorteta_Ptr)*2+1][*N_Ptr+1]
I don't quite think this is doing what you think it is doing. While I haven't seen something like this myself before, I believe that this is telling the compiler to create a variable length 2D array for you based on the other given parameters. Then, you fill in these values in your function. But, because you don't return this value nor do you declare it as pass by reference, it is thrown away when you return, thus the work is lost and you have garbage in your array in main(). Better form would be to create this array in main(), then pass it in by reference something like double *AP[][], or return this array upon exit, or hack things up even worse than this function and just make it a global so that you can see it anywhere.
Related
I am trying to make a c-program that will will a string, but I want it only to read a very small part of it.
The NMEA-telegram that I try to read is $WIXDR, and do receive the necessary strings.
Here's 2 examples of strings that I get into the CPU:
$WIXDR,C,1.9,C,0,H,83.2,P,0,P,1023.9,H,0*46
$WIXDR,V,0.01,M,0,Z,10,s,0,R,0.8,M,0,V,0.0,M,1,Z,0,s,1,R,0.0,M,1,R,89.9,M,2,R,0.0,M,3*60
If it were only 1 string (not both C and V), this would not be a problem for me.
The problem here is that it's 2 seperate strings. One with the temperature, and one with rain-info.
The only thing that I'm interested in is the value "1.9" from
$WIXDR,C,1.9,C,0......
Here's what I have so far:
void ProcessXDR(char* buffPtr)
{
char valueBuff[10];
int result, x;
float OutSideTemp;
USHORT uOutSideTemp;
// char charTemperature, charRain
IODBerr eCode;
//Outside Temperature
result = ReadAsciiVariable(buffPtr, &valueBuff[0], &buffPtr, sizeof(valueBuff));
sscanf(&valueBuff[0],"%f",&OutSideTemp);
OutSideTemp *= 10;
uOutSideTemp = (USHORT)OutSideTemp;
eCode = IODBWrite(ANALOG_IN,REG_COM_XDR,1,&uOutSideTemp,NULL);
}
// XDR ...
if(!strcmp(&nmeaHeader[0],"$WIXDR"))
{
if(PrintoutEnable)printf("XDR\n");
ProcessXDR(buffPtr);
Timer[TIMER_XDR] = 1200; // Update every minute
ComStateXDR = 1;
eCode = IODBWrite(DISCRETE_IN,REG_COM_STATE_XDR,1,&ComStateXDR,NULL);
}
There's more, but this is the main part that I have.
I have found the answer to my own question. The code that would do as I intented is as follows:
What my little code does, is to look for the letter C, and if the C is found, it will take the value after it and put it into "OutSideTemp". The reason I had to look for C is that there is also a similar string received with the letter V (Rain).
If someone have any input in a way it could be better, I don't mind, but this little piece here does what I need it to do.
Here's to example telegrams I receive (I wanted the value 3.0 to be put into "OutSideTemp"):
$WIXDR,C,3.0,C,0,H,59.2,P,0,P,1026.9,H,04F
$WIXDR,V,0.00,M,0,Z,0,s,0,R,0.0,M,0,V,0.0,M,1,Z,0,s,1,R,0.0,M,1,R,89.9,M,2,R,0.0,M,358
void ProcessXDR(char* buffPtr)
{
char valueBuff[10];
int result, x;
float OutSideTemp;
USHORT uOutSideTemp;
// char charTemperature, charRain
IODBerr eCode;
// Look for "C"
result = ReadAsciiVariable(buffPtr, &valueBuff[0], &buffPtr, sizeof(valueBuff));
// sscanf(&valueBuff[0],"%f",&charTemperature);
if (valueBuff[0] == 'C')
//Outside Temperature
result = ReadAsciiVariable(buffPtr, &valueBuff[0], &buffPtr, sizeof(valueBuff));
sscanf(&valueBuff[0],"%f",&OutSideTemp);
OutSideTemp *= 10;
uOutSideTemp = (USHORT)OutSideTemp;
eCode = IODBWrite(ANALOG_IN,REG_COM_XDR,1,&uOutSideTemp,NULL);
}
The code I wrote below is objection detection using size-invariant template matching. This technique was detailed in the following site: https://www.google.com/url?hl=en&q=http://www.pyimagesearch.com/2015/01/26/multi-scale-template-matching-using-python-opencv/&source=gmail&ust=1489552541603000&usg=AFQjCNHSfgL_RTy-o5SMyCmWELFbsfOOTw
The function works fine. However, when I am running too many iterations in the while loop, OpenCV Error: Insufficient Memory will occur.
I can't seem to figure out why I'm running into this error as I'm releasing the the matrix data that I'm creating in cvCreateMat in every iteration. The memory error occurs after running the loop several times and in the function cvMatchTemplate. Am I missing another source of error? I am writing this code in C on the LCDK.
Function:
double minVal = 0.0;
double maxVal = 0.0 ;
CvPoint minLoc;
CvPoint maxLoc;
double ratio = 1.0;
CvMat* mask2 = NULL;
//for containing the maximum values
CvMat* resized_source;
CvMat* result; //result stored for every shapes
while (1){
// All templates are sized around the same
if(width_curr <= template->cols || height_curr <= template->rows)
break;
resized_source = cvCreateMat(height_curr,width_curr,CV_8UC1);
cvResize(source_close_edge_dist_8,resized_source,CV_INTER_LINEAR);
result = cvCreateMat((resized_source->rows)-(template->rows)+1, (resized_source->cols)-(template->cols)+1, CV_32FC1);
cvMatchTemplate(resized_source, template, result, CV_TM_CCOEFF);
//Detecting several objects
cvMinMaxLoc(result, &minVal, &maxVal, &minLoc, &maxLoc, mask2);
*(max_all+*size) = maxVal;
(max_all_point+*size)->x = maxLoc.x;
(max_all_point+*size)->y = maxLoc.y;
*(max_all_ratio+*size) = sqrt(ratio);
*size = *size + 1;
// move on to next resizing
ratio -= 0.04;
width_curr = sqrt(ratio)*width;
height_curr = sqrt(ratio)*height;
minVal = 0.0;
maxVal =0.0 ;
cvReleaseData(resized_source);
cvReleaseMat(&resized_source);
cvReleaseData(result);
cvReleaseMat(&result);
}
Given a C file, I want to compute the backward slice for some criteria and compare the slice to the original code. Because I don't want to implement a slicing program from cratch, I've already tried to get used to Frama-C which seems to help with this task.
However, my problem is, that Frama-C's slicing plugin changes the preprocessed input code, so that it makes it harder to identify which lines of the original also appear in the slice.
Example:
Input file test1.c:
double func1(double param) {
return 2+param;
}
int main() {
int a=3;
double c=4.0;
double d=10.0;
if(a<c)
c=(double)a/4.0;
double res = func1(c);
return 0;
}
Preprocessed file (yielded by frama-c test1.c -print -ocode test1_norm.c):
/* Generated by Frama-C */
double func1(double param)
{
double __retres;
__retres = (double)2 + param;
return __retres;
}
int main(void)
{
int __retres;
int a;
double c;
double d;
double res;
a = 3;
c = 4.0;
d = 10.0;
if ((double)a < c) c = (double)a / 4.0;
res = func1(c);
__retres = 0;
return __retres;
}
Slice (yielded by frama-c -slice-calls func1 test1.c -then-on 'Slicing export' -print):
/* Generated by Frama-C */
double func1_slice_1(double param)
{
double __retres;
__retres = (double)2 + param;
return __retres;
}
void main(void)
{
int a;
double c;
double res;
a = 3;
c = 4.0;
c = (double)a / 4.0;
res = func1_slice_1(c);
return;
}
Note that the signature of main differs and that the name of func1 was changed to func1_slice_1.
Is there a way to suppress that behaviour in order to make the slice and the (preprocessed) original more easily comparable (in terms of a computable diff)?
First, to clarify a simpler question that you don't need answering but that someone searching for the same keywords could, you cannot have the sliced program printed as a selection of the lines of the original program (most of the differences between the two corresponds to lost information, basically. If the information was there, it would be used to print the most resembling program possible).
What you can do is print Frama-C's representation of the original program, which you are already doing with frama-c test2.c -print -ocode test2_norm.c.
To solve your problem of func1 being renamed to func1_slice_1, you can try playing with option -slicing-level 0:
$ frama-c -slicing-level 0 -slice-calls func1 test1.c -then-on 'Slicing export' -print
...
/* Generated by Frama-C */
double func1(double param)
{
double __retres;
__retres = (double)2 + param;
return __retres;
}
void main(void)
{
int a;
double c;
double res;
a = 3;
c = 4.0;
c = (double)a / 4.0;
res = func1(c);
return;
}
I think this will prevent the slicer from slicing inside func1 at all. The help says:
-slicing-level <n> set the default level of slicing used to propagate to the
calls
0 : don't slice the called functions
1 : don't slice the called functions but propagate the
marks anyway
2 : try to use existing slices, create at most one
3 : most precise slices
So, I am creating a GUI in which you are able to calculate either the molar mass, mass or moles and I cannot seem to get a calculation back when I call my methods. I am using parallel arrays and I am thinking that may be the problem. Btw, molarMass was declared globally but I didn't know how to format it on here. Thanks.
private void btnGoActionPerformed(java.awt.event.ActionEvent evt) {
int indexOfElements = cmbElements.getSelectedIndex();
Double numberOfMass = Double.parseDouble(txtInputMass.getText());
Double numberOfMoles = Double.parseDouble(txtInputMoles.getText());
if (chkMoles.isSelected()==true)
{
txtAnswer.setText(solveForMoles(numberOfMass).toString() + " mol");
}
else if (chkMolarMass.isSelected()==true)
{
txtAnswer.setText(solveForMolarMass(numberOfMass, numberOfMoles).toString() + "
g/mol");
}
else if (chkMass.isSelected()==true)
{
txtAnswer.setText(solveForMass(numberOfMoles).toString() + " g");
}
else
{
txtAnswer.setText ("Please make a selection");
}
private Double solveForMoles (double mass){
int indexOfElements = cmbElements.getSelectedIndex();
double numberOfMoles = mass/molarMass[indexOfElements];
return (Double.parseDouble (x.format(numberOfMoles)));
}
private Double solveForMass (double moles){
int indexOfElements = cmbElements.getSelectedIndex();
double numberOfMass = moles*molarMass[indexOfElements];
return (Double.parseDouble (x.format(numberOfMass)));
}
private Double solveForMolarMass (double masss, double moless){
double numberOfMolarMass = masss/moless;
return (Double.parseDouble(x.format (numberOfMolarMass)));
}
I'd recommend that you make some changes:
Encapsulate all those calculations into a sensible Java object rather than parallel arrays. Java's an object-oriented language.
Move all the calculations outside of the UI. Write that calculation object, JUnit test it thoroughly, then introduce it into the UI. Computer science, and all problem solving, is best done using divide and conquer.
I want to extend the Maple CodeGeneration[C] by a handler for the piecewise function (no idea why it is not included).
To this end I did:
with(CodeGeneration):
with(LanguageDefinition):
LanguageDefinition:-Define("NewC", extend="C",
AddFunction("piecewise", anything::numeric,
proc()
local i;
Printer:-Print("if(",_passed[1],"){",_passed[2],"}");
for i from 3 to _npassed-2 by 2 do
Printer:-Print("else if(",_passed[i],"){",_passed[i+1],"}");
end do;
Printer:-Print("else{",_passed[_npassed],"}");
end proc,
numeric=double)
);
Note that I am using if else statements in favour of case statements on puropose.
Here is an example code to translate:
myp:=proc(x::numeric)
piecewise(x>1,1*x,x>2,2*x,x>3,3*x,0);
end proc:
Translate(myp, language="NewC");
The output is
void myp (double x)
{
if(0.1e1 < x){x}else if(0.2e1 < x){0.2e1 * x}else if(0.3e1 < x){0.3e1 * x}else{0};
;
}
For a valid C-routine I obviously need to replace the curly brackets like
{x}
by something like
{result=x;}
and analogous for the others. I could do this by hand by modifying the strings in the above AddFunction statement. But then the variable name result is not known to the code generator, so there will not be any declaration nor will the value of result be returned as needed to match the routine myp or any more complicated procedure in which the result of piecewise may be assigned to some other variable or used in computations. So how do I treat this properly in the CodeGeneration routines? I.e. how can I get a valid variable name etc.
How about something like this?
restart:
with(CodeGeneration):
with(LanguageDefinition):
LanguageDefinition:-Define("NewC", extend="C",
AddFunction("piecewise", anything::numeric,
proc()
local i;
Printer:-Print("( (",_passed[1],") ? ",_passed[2]);
for i from 3 to _npassed-2 by 2 do
Printer:-Print(" : (",_passed[i],") ? ",_passed[i+1]);
end do;
Printer:-Print(" : ",_passed[_npassed]," ) ");
end proc,
numeric=double)
);
myp:=proc(x::numeric) local result::numeric;
result := piecewise(x>3,3*x,x>2,2*x,x>1,1*x,0);
end proc:
Translate(myp, language="NewC");
double myp (double x)
{
double result;
result = ( (0.3e1 < x) ? 0.3e1 * x : (0.2e1 < x) ? 0.2e1 * x : (0.1e1 < x) ? x : 0 ) ;
return(result);
}
[edited, to add the material below]
It turns out that CodeGeneration[C] does handle piecewise, but only if the optimize option is supplied. (I'll submit a bug report, that it should be handled by default.)
restart:
with(CodeGeneration):
with(LanguageDefinition):
myp:=proc(x::numeric) local result::numeric;
result:=piecewise(x>3,3*x,x>2,2*x,x>1,1*x,0);
end proc;
myp := proc(x::numeric)
local result::numeric;
result := piecewise(3 < x, 3*x, 2 < x, 2*x, 1 < x, x, 0)
end proc;
Translate(myp, language="C", optimize);
double myp (double x)
{
double result;
double s1;
if (0.3e1 < x)
s1 = 0.3e1 * x;
else if (0.2e1 < x)
s1 = 0.2e1 * x;
else if (0.1e1 < x)
s1 = x;
else
s1 = 0.0e0;
result = s1;
return(result);
}
As you can see, piecewise is handled above by translation to a separate if(){..} block, with assignment to an introduced temporary variable. That temporary is subsequently used wherever the piecewise call existed in the Maple procedure. And the temporary is declared. Nice and automatic. So that might suffice for your use of piecewise.
You also asked how you could both introduce and declare such temporary variables in your own extensions (if I understand you rightly). Continuing on in the same Maple session from above, here are some ideas along those lines. An unassigned global name is generated. The myp procedure is put into inert form, to which the new local variable is added. And then that altered inert form is turned back into an actual procedure. As an illustration, I used a modified version of your original extension to handle piecewise. This all produces something close to acceptable. The only snag is that the assignment statement,
result = temporary_variable;
is out of place! It lies before the piecewise translation block. I don't yet see how to repair that in the method.
LanguageDefinition:-Define("NewC", extend="C",
AddFunction("piecewise", anything::numeric,
proc()
global T;
local i, t;
t:=convert(T,string);
Printer:-Print(t,";\n");
Printer:-Print(" if (",_passed[1],
")\n { ",t," = ",_passed[2],"; }\n");
for i from 3 to _npassed-2 by 2 do
Printer:-Print(" else if (",_passed[i],")\n { ",
t," = ",_passed[i+1],"; }\n");
end do;
Printer:-Print(" else { ",t," = ",_passed[_npassed],"; }");
end proc,
numeric=double)
):
T:=`tools/genglobal`('s'):
newmyp := FromInert(subsindets(ToInert(eval(myp)),'specfunc(anything,_Inert_LOCALSEQ)',
z->_Inert_LOCALSEQ(op(z),
_Inert_DCOLON(_Inert_NAME(convert(T,string)),
_Inert_NAME("numeric",
_Inert_ATTRIBUTE(_Inert_NAME("protected",
_Inert_ATTRIBUTE(_Inert_NAME("protected")
))))))));
newmyp := proc(x::numeric)
local result::numeric, s::numeric;
result := piecewise(3 < x, 3*x, 2 < x, 2*x, 1 < x, x, 0)
end proc;
Translate(newmyp, language="NewC");
double newmyp (double x)
{
double result;
double s;
result = s;
if (0.3e1 < x)
{ s = 0.3e1 * x; }
else if (0.2e1 < x)
{ s = 0.2e1 * x; }
else if (0.1e1 < x)
{ s = x; }
else { s = 0; };
return(result);
}
If you rerun the last three statements above (from the assignment to T, through to the Translate call) then you should see a new temp variable used, such as s0. And then s1 if repeated yet again. And so on.
Perhaps this will give you some more ideas to work with. Cheers.