I have written the following code for my project. The code is scattered across various files and quite long so i am posting the minimal code.
#include<stdio.h>
#include<stdbool.h>
struct TwoPoint
{
int width;
int value;
};
struct Module
{
int categ;
void *ptr;
};
struct Rect
{
struct TwoPoint val;
struct TwoPoint val_new;
bool is_changed;
};
struct S
{
int numInstances;
struct Module instances[20];
struct Rect RectList[40];
int numRect;
}s1;
struct Test
{
int categ;
struct Rect state;
};
struct TwoPoint initPVal(int v,int w)
{
struct TwoPoint temp;
temp.value=v;
temp.width=w;
return temp;
}
int getValue(struct TwoPoint *b)
{
return (b->value);
}
struct TwoPoint get(struct Rect *r)
{
return (r->val);
}
void initialize()
{
s1.numInstances=0;
s1.numRect=0;
}
void addRect(struct Rect *r)
{
if(s1.numRect<40)
{
s1.RectList[s1.numRect].val=r->val;
s1.RectList[s1.numRect].val_new=r->val_new;
s1.RectList[s1.numRect].is_changed=r->is_changed;
s1.numRect++;
}
}
struct Rect initRect(struct TwoPoint initval)
{
struct Rect temp;
struct TwoPoint tempP;
tempP=initPVal(0,0);
temp.val=initval;
temp.val_new=tempP;
temp.is_changed=false;
addRect(&temp);
return temp;
}
void copy(struct Rect *r)
{
if(r->is_changed)
{
r->val= r->val_new;
r->is_changed=false;
}
}
void copyRect()
{
int i=0;
for(i=0;i<s1.numRect;i++)
{
copy(&s1.RectList[i]);
}
}
void setInstance(struct Module *m)
{
s1.instances[s1.numInstances].categ=m->categ;
s1.instances[s1.numInstances].ptr=m->ptr;
s1.numInstances++;
if (s1.numInstances >= 20)
{
printf("Too many instances");
}
}
void setModule(struct Test *t)
{
struct Module m;
m.categ=t->categ;
m.ptr=&t;
setInstance(&m);
}
void init(struct Test *t)
{
t->categ=2;
struct Rect tr;
struct TwoPoint tb1=initPVal(0,5);
tr=initRect(tb1);
t->state=tr;
}
void actions(struct Test *t)
{
struct TwoPoint tb=get(&t->state);
int y=getValue(&tb);
printf("%d\n",y);
unsigned int x=getValue(&tb);
printf("%u\n",x);
switch(y)
{
....
}
}
void initS()
{
init(s1.instances[0].ptr);
}
void act()
{
actions(s1.instances[0].ptr);
}
void setup()
{
struct Test t;
initialize();
init(&t);
setModule(&t);
}
void run()
{
initS();
act();
copyRect();
}
int main()
{
printf("foo\n");
setup();
printf("bar\n");
run();
return 0;
}
There are two errors:
- The init() function when called through initS() function leads to Stack Overdumped error whereas it worked fine while i called it in setup(). I think Call is correct as action() function is being executed.
- The second problem is in actions() function. When i am calculating the value of y to be used as switch condition instead of the value being 0,1,2 or 3 it is some memory address which i found by printing it while trying to debug.
The problem is:
A
Teststructure is allocated as a local stack variable and then the address of it assigned to some variable which is accessed later. The next time this variable is accessed is in (init):At this point the pointer points to a variable that has fallen out of scope, resulting in undefined behaviour. What actually happens is that the stack gets smashed because of the structure assignment which is attempted. This is why it’s also difficult to get a backtrace.
One solution is to allocate the memory with
malloclike so:Another problem existed, namely a semantic bug in
setModule:m.ptr=&tshould actually bem.ptr = t. The assignment of a pointer to aTeststructure was intended. Instead, what happened was that the address of a stack variable holding a pointer to aTeststructure (double pointer to aTeststructure) was assigned.