Calling Convention error - C - c

In the following code there is a calling convention error(possibly leading to an eternal loop), and i cannot detect it. I try to verify the code using 'Satabs'. What kind of model can bring the error to the surface. With the following model i get a segfault.
By changing the VLEN and TMAX you can play a bit.
Q1. What is the calling convention error?
Q2. What kind of model would be most appropriate to use for finding the error?
#include <stdio.h>
#if MODEL==1
#define VLEN 3
#define TMAX 4
int trans(int T,int*src,int*dst){
if (T < VLEN && T < TMAX && src[T] < 4){
dst[T]=src[T]+1;
return 1;
} else {
return 0;
}
}
#endif
struct next_state {
int next;
int src[VLEN];
};
typedef struct next_state *iterator_t;
void init(iterator_t iter,int *src){
for(int i=0;i<VLEN;i++){
iter->src[i]=src[i];
}
iter->next=0;
}
int next(iterator_t iter,int *dst){
#ifdef FIX_ARRAY
for(int i=0;i<VLEN;i++){
#else
for(int i=0;i<TMAX;i++){
#endif
dst[i]=iter->src[i];
}
int res=0;
while(!res&&iter->next<TMAX){
res=trans(iter->next,iter->src,dst);
iter->next++;
}
return res;
}
int find_depth(iterator_t iter,int *src){
int table[VLEN*TMAX];
int N=0;
init(iter,src);
for(int i=0;i<TMAX;i++){
if(next(iter,&(table[N*VLEN]))){
N++;
}
}
int depth=0;
for(int i=0; i<N;i++){
printf("Eimai stin for \n");
int tmp=find_depth(iter,&(table[i*VLEN]));
printf("tmp= %d\n",tmp);
if(tmp>=depth){
depth=tmp+1;
//assert(depth);
}
}
printf("\n\n");
return depth;
}
int main(int argc,char*argv[]){
int state[VLEN];
struct next_state ns;
for(int i=0;i<VLEN;i++){
state[i]=0;
}
int depth=find_depth(&ns,state);
printf("depth is %d\n",depth);
}

int depth=find_depth(&ns,state);
You are passing &ns, but taking arg in function as iterator_t iter, is this correct ?
void init(iterator_t iter,int *src){
for(int i=0;i<VLEN;i++){
iter->src[i]=src[i];
iter->src[i] is this expression fine?

I dont know 'Satabs' but the most promising candidate for an endless loop for me seems to be
while(!res&&iter->next<TMAX){
res=trans(iter->next,iter->src,dst);
iter->next++;
}
All other loops rather look like fix count.
This loop might be dangerous for itself even without the so called calling convention error, which doest jump to my eye yet.
Anyhow you should take a look not only to the call of the funtion trans but the whole call tree to it.
You could also try to paste your code there
http://gimpel-online.com//cgi-bin/genPage.py?srcFile=intro.txt&cgiScript=analyseCode.py&title=Introduction+and+Welcome&intro=Introducing+the+testing+facility&compilerOption=online32.lnt&in
Maybe you get a few more hints.
Just a guess:
Maybe 'Satabs' doesn't like undefined preprocessor conditions
like
#if MODEL==1

Related

Function in C only working when an unrelated line is present

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct card_t{
char value;
char suit[50];
} card_t;
card_t draw(){
card_t karta;
int v = (rand() % 13)+2;
int s = (rand() % 4)+1;
if(v<=9){
karta.value = v +'0';
}else{
if (v==10)
karta.value='T';
if (v==11)
karta.value='J';
if (v==12)
karta.value='Q';
if (v==13)
karta.value='K';
if (v==14)
karta.value='A';
}
if (s==1)
strcpy(karta.suit, "of Spades");
if (s==2)
strcpy(karta.suit, "of Hearts");
if (s==3)
strcpy(karta.suit, "of Diamonds");
if (s==4)
strcpy(karta.suit, "of Clubs");
return karta;
}
void face_up(card_t deck[],int size){
for(int i=0;i<=size;i++){
printf("%c %s\n",deck[i].value ,deck[i].suit);
}
}
int main()
{
int size;
card_t *deck;
deck = malloc(100*sizeof(char));
card_t karta;
karta=draw();
for (int i=0; i<100 ; i++){
deck[i]=karta;
if(strcmp(deck[i].suit,"of Spades")==0 && deck[i].value=='A'){
size=i;
break;
}
karta=draw();
/*THIS ONE*/printf("%c %s\n",deck[i].value ,deck[i].suit);
}
face_up(deck,size);
free(deck);
return 0;
}
If I remove the line marked with /THIS ONE/ , the function face_up won't print anything , but if the line is there it works. Any ideas ? Tried it several times and its the same thing .
I would get double print if i leave it there , which i dont need.
Im sorry for the bad code / formatting but i am kinda new to this and yeah ...
Thank you for your help in advance.
This line here deck = malloc(100*sizeof(char)); allocates memory on the heap to store an array of 100 chars. What you want to do, is to allocate an array of 100 card_t. To do this just replace the statement with the following one:
deck = malloc(100*sizeof(card_t));

Swap using only two variables not working

I was writing a C code for quick sort but something went wrong. After some debugging i finally found where my code was going wrong.
When i replaced
{
a[lp]+=a[ub];
a[ub]=a[lp]-a[ub];
a[lp]=a[lp]-a[ub];
}
with
{
tmp=a[lp];
a[lp]=a[ub];
a[ub]=tmp;
}
my code started working.
I am Curious to know why my initial implementation of swapping didn't work?
Can anyone help me?
#include<stdio.h>
#define swap(a,b) (a)=(a)+(b);b=(a)-(b);(a)=(a)-(b);
int a[]={7,1,5,2,3};
int partition(int lb,int ub)
{
int k,hp,lp;
k=a[ub];
lp=lb-1;
for(hp=lb;hp<ub;hp++)
{
if(a[hp]<k)
{
lp++;
int tmp=a[lp];
a[lp]=a[hp];
a[hp]=tmp;
}
}
lp++;
a[lp]+=a[ub];
a[ub]=a[lp]-a[ub];
a[lp]=a[lp]-a[ub];
return lp;
}
void quicksort(int lb,int ub)
{
if(lb<ub)
{
int pos=partition(lb,ub);
quicksort(lb,pos-1);
quicksort(pos+1,ub);
}
}
int main()
{
quicksort(0,4);
int i;
for(i=0;i<5;i++)printf("%d ",a[i]);
printf("\n");
return 0;
}
You need to consider what happens when lp == ub (ie. you are being asked to swap an element with itself).
Change it to this:
if (lp != ub) {
a[lp]+=a[ub];
a[ub]=a[lp]-a[ub];
a[lp]=a[lp]-a[ub];
}
Example: http://ideone.com/AS1Dgf

Optimising a naive piece of code for counters in C. Need a better solution

I am using three counters c1, c2 and c3 in my code for one of the processes in the system. At certain points I need to trigger each of the counters and end it at a particular point(targetc1,targetc2,targetc3). So I am using three flags cf1,cf2 and cf3 to check if the counter flag is set ON whenever my process is triggered and then checking against the counter target if it reached the end point. Is there a better way to do it rather than using three flags? I may need to use more counters in future in my code but it shouldnt exceed some 6 counters I presume.
Code snippet is given below for p1 process to explain my problem.
/*P1 process variables*/
static int c1,c2,c3;
static int targetc1,targetc2,targetc3;
static int cf1,cf2,cf3;
p1startingfunction()
{
int a;
if(cf1 == 1)
{
c1++;
if(c1==targetc1)
/*counter reached do something*/
c1trigger();
}
if(cf2 == 1)
{
c2++;
if(c2==targetc2)
/*counter reached do something*/
c2trigger();
}
if(cf3 == 1)
{
c3++;
if(c3==targetc3)
/*counter reached do something*/
c3trigger();
}
}
There is still lots of room for improvement with this, but this answer is specifically for minimizing code repetition.
With that said, you could use arrays:
/*P1 process variables*/
static int c[3];
static int targetc[3];
static int cf[3];
static void (*ctrigger[3])(void);
p1startingfunction()
{
int a, i;
for (i = 0; i < 3; i++) {
if (cf[i] == 1) {
c[i]++;
if (c[i] == targetc[i]) {
/* counter reached do something */
ctrigger[i]();
}
}
}
}
Or you could use a struct that looks something like:
struct counter {
int c;
int target;
int f;
void (*trigger)(void);
};
And then create an array of structs.
struct counter counters[3];

Spoj - Mixtures

Ok this has been driving me crazy. I solved a problem on spoj called MIXTURES (http://www.spoj.com/problems/MIXTURES/). I don't know why i keep getting segmentation fault. There is also one catch in the problem that there is no explicit indicator for end of input. I think I have handled it correctly but correct me if I am wrong. Here is my code
#include<stdio.h>
#include<stdlib.h>
typedef struct temp
{
int modSum; //the modular sum of the cluster
int smoke; //the minimum smoke that a cluster can give.
}clusterInfo;
int fxDP(int *A,int len)
{
int i,j,k,smoke1,smoke2;
clusterInfo **dpArr=(clusterInfo **)malloc(sizeof(clusterInfo *)*(len-1));
for(i=0;i<len-1;i++)
dpArr[i]=(clusterInfo *)malloc(sizeof(clusterInfo)*(len-i-1)); //len- ( (i+2) -1)= len-i-1
//dpArr[i] gives info of all clusters of length i+2
//base case for clusterLength=2
for(i=0;i<len-1;i++)
{
dpArr[0][i].modSum=(A[i]+A[i+1])%100;
dpArr[0][i].smoke=A[i]*A[i+1];
}
//endBase Case
//induction
for(i=1;i<len-1;i++) //lengthOfCluster=i+2
{
for(j=0;j<len-i-1;j++) //len-i-1+i+2-1=len
{
smoke1=(dpArr[i-1][j].modSum*A[j+(i+2)-1]) + dpArr[i-1][j].smoke;
smoke2=(A[j]*dpArr[i-1][j+1].modSum) + dpArr[i-1][j+1].smoke;
dpArr[i][j].smoke=smoke1<smoke2 ? smoke1:smoke2 ;
dpArr[i][j].modSum=(dpArr[i-1][j].modSum+A[j+(i+2)-1])%100;
}
}
int result=dpArr[len-2][0].smoke;
free(dpArr);
return result;
}
int main()
{
int *A; int len,i;
while(1)
{
scanf("%d",&len);
if(feof(stdin)) break;
A=(int *)malloc(sizeof(int)*len);
for(i=0;i<len;i++)
scanf("%d",&A[i]);
printf("%d\n",fxDP(A,len));
}
return 0;
}
int result=dpArr[len-2][0].smoke;
What happens if len=1 ??

How to use two parameters pointing to the same structure in one function?

I have my code below that consits of a structure, a main, and a function. The function is supposed to display two parameters that have certain values, both of which point to the same structure.
The problem I dont know how to add the SECOND parameter onto the following code :
#include<stdio.h>
#define first 500
#define sec 500
struct trial{
int f;
int r;
float what[first][sec];
};
int trialtest(trial *test);
main(){
trial test;
trialtest(&test);
}
int trialtest(trial *test){
int z,x,i;
for(i=0;i<5;i++){
printf("%f,(*test).what[z][x]);
}
return 0;
}
I need to add a new parameter test_2 there (IN THE SAME FUNCTION) using this code :
for(i=0;i<5;i++){
printf("%f,(*test_2).what[z][x]);
How does int trialtest(trial *test) changes ?
and how does it change in main ?
I know that I should declare test_2 as well, like this :
trial test,test_2;
But what about passing the address in the function ? I do not need to edit it right ?
trialtest(&test); --- This will remain the same ?
So please, tell me how would I use test_2 as a parameter pointing to the same structure as test, both in the same function..
Thank you !!
Please tell me if you need more clarification
I think that this is your homework, so I'll just write a different function that may give you an idea of what (I think) you need to do. I read that you don't want to change the trail_test parameter list, so I stuck with a similar parameter list.
struct thing {
/* put some stuff here */
};
typedef struct thing thing; /* because this is C, not C++ */
int how_many_things(thing * thing_list);
int main(void) {
int i;
thing * a;
int count_init = random(); /* let's surprise ourselves and make a random number of these */
count_init %= 128; /* but not too many or it might not work at all */
a = malloc(count_init*sizeof(things)+1);
for (i = 0; i < count_init; i++) {
thing_init(&(a[i]));
}
make_illegal_thing(&(a[count_init]) ); /* like '\0' at the end of a string */
printf("There are %i things in the list\n", how_many_things(a) );
return 0;
}
/* This is very similar to strlen */
int how_many_things(thing * a) {
int count = 0;
while (is_legal_thing(a) ) {
a++;
count++;
}
return count;
}

Resources