encountered strange situation-variable value - c

I am programming on some device and I encountered
rather strange situation.
The same variable - for the first time has correct value,
but the SAME variable on a different place in code,
has a DIFFERENT value.
What can be causing this? I am pretty sure I didn't modify
the variable in between, I am also pretty sure I didn't
modify the variable using some pointers accidentally.
What can be causing this? I am really confused?
Can it be related that I for example used whole available stack
space of some function - and because of this compiler automatically
0-ifies my variable(or something similar)?
I have some long code inside a single function f.
Here's whole details on usage of pointsEntered variable in my code (how it is used).
/* Let the user input points */
s32 pointsEntered = 0;
int pointsCounter = 0;
while(1)
{
if(pointsCounter == 3)
return; // User entered wrong points 3 times, exit function
bool retStatus = false;
retStatus = inputPoints(&pointsEntered);
if(false == retStatus) // If user didn't enter amount, exit this function
return;
if(pointsEntered>atoi(userAmount)){
PromptBox(false, 0, "Points should not be more\n than current points");
pointsCounter++;
continue;
}
break;
}
// PROBLEM: pointsEntered - is OK here but as it will be shown below, it gets modified down the way
// even though I don't change it directly
char intTest1[50];
sprintf(intTest1, "1pentered %d", pointsEntered); // Here the value is OK! It shows value that I entered, e.g., 220
PromptBox(false, 0, intTest1);
/* Let the user enter 4 digit pin code */
u8 pinEntered[5] = {0};
bool retStatus1 = false;
retStatus1 = inputPin(pinEntered);
pinEntered[5]='\0';
if(false == retStatus1) // If user didn't enter amount, exit this function
return;
char intTest2[50];
sprintf(intTest2, "2pentered %d", pointsEntered); // Here pointsEnetered is OK
PromptBox(false, 0, intTest2);
/* Compute hash of pin code*/
s32 siRet1 = 0;
u8 pinVerify[25]={0};
u8 hashResult[16] = {0};
memcpy(pinVerify,pinEntered,4);
memcpy(&pinVerify[4],"XXXX",21);
siRet1 = sdkMD5(hashResult,pinVerify,25);
char intTest3[50];
sprintf(intTest3, "3pentered %d", pointsEntered); // Here pointsEntered has changed!!!
PromptBox(false, 0, intTest3);
/* convert string hash code to byte array */
unsigned char val[16] = {0};
unsigned char * pos = pinHash;
size_t count = 0;
// WARNING: no sanitization or error-checking whatsoever
for(count = 0; count < sizeof(val)/sizeof(val[0]); count++)
{
sscanf(pos, "%2hhx", &val[count]);
pos += 2 * sizeof(char);
}
char intTest4[50];
sprintf(intTest4, "4pentered %d", pointsEntered);
PromptBox(false, 0, intTest4);
/* Does the pin hash match ? */
if (siRet == SDK_OK && (!memcmp(hashResult,val,16)))
{
MsgBox("PIN OK","",0,SDK_KEY_MASK_ESC | SDK_KEY_MASK_ENTER);
}
else
{
MsgBox("PIN doesn't match-exiting","",0,SDK_KEY_MASK_ESC | SDK_KEY_MASK_ENTER);
return;
}
char intTest[50];
sprintf(intTest, "pentered %d", pointsEntered);
PromptBox(false, 0, intTest);

These two lines may cause it (as it's undefined behavior):
u8 pinEntered[5] = {0};
...
pinEntered[5]='\0';
Here you declare an array of five entries, but then you assign to a sixth item. This will most likely overwrite any previous variable on the stack.

Related

Dynamically allocate and initialize new object with 30% probability

I'm writing a program that will simulate a randomized race between runners who are climbing up a mountain where dwarf orcs (dorcs) are coming down the mountain to attack the runners. It begins with two runners named harold and timmy at the bottom of the mountain. The runners make their way up the mountain in randomized moves where they may make progress forward up the mountain, or they may slide back down the mountain. Dorcs are randomly generated, and they inflict damage on a runner if they collide. The simulation ends when one of the runners reaches the top of the mountain, or when both runners are dead.
I'm struggling with a part where I have to implement the actual race loop. Once the race is initialized, the race loop will iterate until the race is over. This happens when either a winner has been declared, or when all runners are dead.
Every iteration of the race loop will do the following:
with 30% probability, dynamically allocate a new dorc as an EntityType structure, and initialize it as follows:
(a) a dorc’s avatar is always “d”
(b) each dorc begins the race at the top of the mountain, which is at row 2
(c) with equal probability, the dorc may be placed either in the same column as timmy, or in the same column as the harold, or in the column exactly half-way between the two
(d) add the new dorc to the race’s array of dorcs
(e) using the pthread_create() function, create a thread for the new dorc, and save the thread pointer in the dorc’s entity structure; the function that each dorc thread will execute is the void* goDorc(void*) function that you will implement in a later step; the parameter to the goDorc() function will be the EntityType pointer that corresponds to that dorc
I guess I'm confused with the logic of how to approach this. I decided to make a function called isOver() to indicate if the race is over, and then a separate function called addDorc() to initialize the Dorc elements and do all the requirements above.
In isOver(), I attempt to add a dorc object to the dorcs array by doing addDorc(race); with every iteration of the race loop/if the race hasn't ended or no one died. But I keep getting the error:
control.c:82:3: error: too few arguments to function ‘addDorc’
addDorc(race);
The problem is I don't think I can manually declare all the parameters in addDorc() because some elements like the "path" argument are based on probability. As mentioned above, with equal probability, the dorc may be placed either in the same column as timmy, or in the same column as the harold, or in the column exactly half-way between the two. The issue is I don't know how to factor this random value when calling addDorc() and would appreciate some help. I also don't know if I'm doing the "with 30% probability, dynamically allocate a new dorc as an EntityType structure" correctly and would be grateful for some input on that as well.
defs.h
typedef struct {
pthread_t thr;
char avatar[MAX_STR];
int currPos;
int path;
} EntityType;
typedef struct {
EntityType ent;
char name[MAX_STR];
int health;
int dead;
} RunnerType;
typedef struct {
int numRunners;
RunnerType *runners[MAX_RUNNERS];
int numDorcs;
EntityType *dorcs[MAX_DORCS];
char winner[MAX_STR];
int statusRow;
sem_t mutex;
} RaceInfoType;
void launch();
int addDorc(RaceInfoType*, char*, int, int);
int isOver(RaceInfoType*);
void initRunners(RaceInfoType*);
int addRunner(RaceInfoType*, char*, char*, int, int, int, int);
int randm(int);
void *goRunner(void*);
void *goDorc(void*);
RaceInfoType *race;
control.c
void launch(){
race = malloc(sizeof(RaceInfoType));
race->numRunners = 0;
initRunners(race);
if (sem_init(&race->mutex, 0, 1) < 0) {
printf("semaphore initialization error\n");
exit(1);
}
strcpy(race->winner, " ");
srand((unsigned)time(NULL));
int i;
for(i = 0; i < race->numRunners; ++i){
pthread_create(&(race->runners[i]->ent.thr), NULL, goRunner, " ");
}
race->numDorcs = 0;
}
int addDorc(RaceInfoType* race, char *avatar, int path, int currPos){
if(race->numDorcs == MAX_DORCS){
printf("Error: Maximum dorcs already reached. \n");
return 0;
}
race->dorcs[race->numDorcs] = malloc(sizeof(EntityType));
int timmysColumn = race->dorcs[race->numDorcs]->currPos;
int haroldsColumn = race->dorcs[race->numDorcs]->currPos;
int halfwayColumn = (timmysColumn+haroldsColumn)/2;
int r = rand()%100;
pthread_t dorc;
if(r <= 30){
strcpy(race->dorcs[race->numDorcs]->avatar, "d");
race->dorcs[race->numDorcs]->currPos = 2;
if(r <= 33){
race->dorcs[race->numDorcs]->path = timmysColumn;
}else if(r <= 66){
race->dorcs[race->numDorcs]->path = haroldsColumn;
}else{
race->dorcs[race->numDorcs]->path = halfwayColumn;
}
pthread_create(&dorc, NULL, goDorc, " ");
}
race->numRunners++;
}
int isOver(RaceInfoType* race){
int i;
for(i = 0; i < race->numRunners; ++i){
if((race->winner != " ") || (race->runners[race->numRunners]->dead = 1)){
return 1;
}
addDorc(race);
return 0;
}
}
void initRunners(RaceInfoType* r){
addRunner(r, "Timmy", "T", 10, 35, 50, 0);
addRunner(r, "Harold", "H", 14, 35, 50, 0);
}
int addRunner(RaceInfoType* race, char *name, char *avatar, int path, int currPos, int health, int dead){
if(race->numRunners == MAX_RUNNERS){
printf("Error: Maximum runners already reached. \n");
return 0;
}
race->runners[race->numRunners] = malloc(sizeof(RunnerType));
strcpy(race->runners[race->numRunners]->name, name);
strcpy(race->runners[race->numRunners]->ent.avatar, avatar);
race->runners[race->numRunners]->ent.path = path;
race->runners[race->numRunners]->ent.currPos = currPos;
race->runners[race->numRunners]->health = health;
race->runners[race->numRunners]->dead = dead;
race->numRunners++;
return 1;
}
Caveat: Because there's so much missing [unwritten] code, this isn't a complete solution.
But, I notice at least two bugs: the isOver bugs in my top comments. And, incrementing race->numRunners in addDorc.
isOver also has the return 0; misplaced [inside the loop]. That should go as the last statement in the function. If you had compiled with -Wall [which you should always do], that should have been flagged by the compiler (e.g. control reaches end of non-void function)
From that, only one "dorc" would get created (for the first eligible runner). That may be what you want, but [AFAICT] you want to try to create more dorcs (one more for each valid runner).
Also, the bug the compiler flagged is because you're calling addDorc(race); but addDorc takes more arguments.
It's very difficult to follow the code when you're doing (e.g.) race->dorcs[race->numDorcs]->whatever everywhere.
Better to do (e.g.):
EntityType *ent = &race->dorcs[race->numDorcs];
ent->whatever = ...;
Further, it's likely that your thread functions would like a pointer to their [respective] control structs (vs. just passing " ").
Anyway, I've refactored your code to incorporate these changes. I've only tried to fix the obvious/glaring bugs from simple code inspection, but I've not tried to recompile or address the correctness of your logic.
So, there's still more work to do, but the simplifications may help a bit.
void
launch(void)
{
race = malloc(sizeof(RaceInfoType));
race->numRunners = 0;
initRunners(race);
if (sem_init(&race->mutex,0,1) < 0) {
printf("semaphore initialization error\n");
exit(1);
}
strcpy(race->winner," ");
srand((unsigned)time(NULL));
int i;
for (i = 0; i < race->numRunners; ++i) {
RunnerType *run = &race->runners[i];
EntityType *ent = &run->ent;
pthread_create(&ent->thr,NULL,goRunner,ent);
}
race->numDorcs = 0;
}
int
addDorc(RaceInfoType* race,char *avatar,int path,int currPos)
{
if (race->numDorcs == MAX_DORCS) {
printf("Error: Maximum dorcs already reached. \n");
return 0;
}
EntityType *ent = malloc(sizeof(*ent));
race->dorcs[race->numDorcs] = ent;
int timmysColumn = ent->currPos;
int haroldsColumn = ent->currPos;
int halfwayColumn = (timmysColumn + haroldsColumn) / 2;
int r = rand()%100;
#if 0
pthread_t dorc;
#endif
if (r <= 30) {
strcpy(ent->avatar,"d");
ent->currPos = 2;
if (r <= 33) {
ent->path = timmysColumn;
} else if (r <= 66) {
ent->path = haroldsColumn;
} else {
ent->path = halfwayColumn;
}
pthread_create(&ent->thr,NULL,goDorc,ent);
}
#if 0
race->numRunners++;
#else
race->numDorcs += 1;
#endif
}
int
isOver(RaceInfoType* race)
{
int i;
for (i = 0; i < race->numRunners; ++i) {
#if 0
if ((race->winner != " ") ||
(race->runners[race->numRunners]->dead = 1))
return 1;
#else
RunnerType *run = &race->runners[i];
if ((race->winner != " ") || (run->dead == 1))
return 1;
#endif
addDorc(race);
#if 0
return 0;
#endif
}
#if 1
return 0;
#endif
}
void
initRunners(RaceInfoType* r)
{
addRunner(r,"Timmy","T",10,35,50,0);
addRunner(r,"Harold","H",14,35,50,0);
}
int
addRunner(RaceInfoType* race,char *name,char *avatar,int path,int currPos,
int health,int dead)
{
if (race->numRunners == MAX_RUNNERS) {
printf("Error: Maximum runners already reached. \n");
return 0;
}
RunnerType *run = malloc(sizeof(*run));
race->runners[race->numRunners] = run;
strcpy(run->name,name);
EntityType *ent = &run->ent;
strcpy(ent->avatar,avatar);
ent->path = path;
ent->currPos = currPos;
run->health = health;
run->dead = dead;
race->numRunners++;
return 1;
}
UPDATE:
I noticed in addDorc(), you put pthread_t dorc; in an if statement. I don't quite understand what my if statement is actually supposed to be checking though.
I forgot to mention/explain. I wrapped your/old code and my/new code with preprocessor conditionals (e.g.):
#if 0
// old code
#else
// new code
#endif
After the cpp stage, the compiler will only see the // new code stuff. Doing this was an instructional tool to show [where possible] what code you had vs what I replaced it with. This was done to show the changes vs. just rewriting completely.
If we never defined NEVERWAS with a #define NEVERWAS, then the above block would be equivalent to:
#ifdef NEVERWAS
// old code ...
#else
// new code
#endif
Would it still be under the if(r <= 30) part like I did in my original code?
Yes, hopefully now, it is more clear. #if is a cpp directive to include/exclude code (as if you had edited that way). But, a "real" if is an actual executable statement that is evaluated at runtime [as it was before], so no change needed.
My other concern is it doesn't look like dorc is used anywhere in the function because you write pthread_create(&ent->thr,NULL,goDorc,ent); which seems to use ent instead?
That is correct. It is not used/defined and the value goes to ent->thr. As you had it, the pthread_t value set by pthread_create would be lost [when dorc goes out of scope]. So, unless it's saved somewhere semi-permanent (e.g. in ent->thr), there would be no way to do a pthread_join call later.

Why does my program keep getting stuck while running the mandelbrot brainf*** program?

I wanted to improve my C skills, so I search some program's ideas.
Someone propose to create a simple Brainf*** interpreter and then a compiler. So here I am.
I created the interpreter and it works as expected, except with the Mandelbrot program:
A mandelbrot set fractal viewer in brainfuck written by Erik Bosman
+++++++++++++[->++>>>+++++>++>+<<<<<<]>>>>>++++++>--->>>>>>>>>>+++++++++++++++[[
>>>>>>>>>]+[<<<<<<<<<]>>>>>>>>>-]+[>>>>>>>>[-]>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>[-]+
<<<<<<<+++++[-[->>>>>>>>>+<<<<<<<<<]>>>>>>>>>]>>>>>>>+>>>>>>>>>>>>>>>>>>>>>>>>>>
>+<<<<<<<<<<<<<<<<<[<<<<<<<<<]>>>[-]+[>>>>>>[>>>>>>>[-]>>]<<<<<<<<<[<<<<<<<<<]>>
>>>>>[-]+<<<<<<++++[-[->>>>>>>>>+<<<<<<<<<]>>>>>>>>>]>>>>>>+<<<<<<+++++++[-[->>>
>>>>>>+<<<<<<<<<]>>>>>>>>>]>>>>>>+<<<<<<<<<<<<<<<<[<<<<<<<<<]>>>[[-]>>>>>>[>>>>>
>>[-<<<<<<+>>>>>>]<<<<<<[->>>>>>+<<+<<<+<]>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>
[>>>>>>>>[-<<<<<<<+>>>>>>>]<<<<<<<[->>>>>>>+<<+<<<+<<]>>>>>>>>]<<<<<<<<<[<<<<<<<
<<]>>>>>>>[-<<<<<<<+>>>>>>>]<<<<<<<[->>>>>>>+<<+<<<<<]>>>>>>>>>+++++++++++++++[[
>>>>>>>>>]+>[-]>[-]>[-]>[-]>[-]>[-]>[-]>[-]>[-]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>-]+[
>+>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>->>>>[-<<<<+>>>>]<<<<[->>>>+<<<<<[->>[
-<<+>>]<<[->>+>>+<<<<]+>>>>>>>>>]<<<<<<<<[<<<<<<<<<]]>>>>>>>>>[>>>>>>>>>]<<<<<<<
<<[>[->>>>>>>>>+<<<<<<<<<]<<<<<<<<<<]>[->>>>>>>>>+<<<<<<<<<]<+>>>>>>>>]<<<<<<<<<
[>[-]<->>>>[-<<<<+>[<->-<<<<<<+>>>>>>]<[->+<]>>>>]<<<[->>>+<<<]<+<<<<<<<<<]>>>>>
>>>>[>+>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>->>>>>[-<<<<<+>>>>>]<<<<<[->>>>>+
<<<<<<[->>>[-<<<+>>>]<<<[->>>+>+<<<<]+>>>>>>>>>]<<<<<<<<[<<<<<<<<<]]>>>>>>>>>[>>
>>>>>>>]<<<<<<<<<[>>[->>>>>>>>>+<<<<<<<<<]<<<<<<<<<<<]>>[->>>>>>>>>+<<<<<<<<<]<<
+>>>>>>>>]<<<<<<<<<[>[-]<->>>>[-<<<<+>[<->-<<<<<<+>>>>>>]<[->+<]>>>>]<<<[->>>+<<
<]<+<<<<<<<<<]>>>>>>>>>[>>>>[-<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>]>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>+++++++++++++++[[>>>>
>>>>>]<<<<<<<<<-<<<<<<<<<[<<<<<<<<<]>>>>>>>>>-]+>>>>>>>>>>>>>>>>>>>>>+<<<[<<<<<<
<<<]>>>>>>>>>[>>>[-<<<->>>]+<<<[->>>->[-<<<<+>>>>]<<<<[->>>>+<<<<<<<<<<<<<[<<<<<
<<<<]>>>>[-]+>>>>>[>>>>>>>>>]>+<]]+>>>>[-<<<<->>>>]+<<<<[->>>>-<[-<<<+>>>]<<<[->
>>+<<<<<<<<<<<<[<<<<<<<<<]>>>[-]+>>>>>>[>>>>>>>>>]>[-]+<]]+>[-<[>>>>>>>>>]<<<<<<
<<]>>>>>>>>]<<<<<<<<<[<<<<<<<<<]<<<<<<<[->+>>>-<<<<]>>>>>>>>>+++++++++++++++++++
+++++++>>[-<<<<+>>>>]<<<<[->>>>+<<[-]<<]>>[<<<<<<<+<[-<+>>>>+<<[-]]>[-<<[->+>>>-
<<<<]>>>]>>>>>>>>>>>>>[>>[-]>[-]>[-]>>>>>]<<<<<<<<<[<<<<<<<<<]>>>[-]>>>>>>[>>>>>
[-<<<<+>>>>]<<<<[->>>>+<<<+<]>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>>[-<<<<<<<<
<+>>>>>>>>>]>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>+++++++++++++++[[>>>>>>>>>]+>[-
]>[-]>[-]>[-]>[-]>[-]>[-]>[-]>[-]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>-]+[>+>>>>>>>>]<<<
<<<<<<[<<<<<<<<<]>>>>>>>>>[>->>>>>[-<<<<<+>>>>>]<<<<<[->>>>>+<<<<<<[->>[-<<+>>]<
<[->>+>+<<<]+>>>>>>>>>]<<<<<<<<[<<<<<<<<<]]>>>>>>>>>[>>>>>>>>>]<<<<<<<<<[>[->>>>
>>>>>+<<<<<<<<<]<<<<<<<<<<]>[->>>>>>>>>+<<<<<<<<<]<+>>>>>>>>]<<<<<<<<<[>[-]<->>>
[-<<<+>[<->-<<<<<<<+>>>>>>>]<[->+<]>>>]<<[->>+<<]<+<<<<<<<<<]>>>>>>>>>[>>>>>>[-<
<<<<+>>>>>]<<<<<[->>>>>+<<<<+<]>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>+>>>>>>>>
]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>->>>>>[-<<<<<+>>>>>]<<<<<[->>>>>+<<<<<<[->>[-<<+
>>]<<[->>+>>+<<<<]+>>>>>>>>>]<<<<<<<<[<<<<<<<<<]]>>>>>>>>>[>>>>>>>>>]<<<<<<<<<[>
[->>>>>>>>>+<<<<<<<<<]<<<<<<<<<<]>[->>>>>>>>>+<<<<<<<<<]<+>>>>>>>>]<<<<<<<<<[>[-
]<->>>>[-<<<<+>[<->-<<<<<<+>>>>>>]<[->+<]>>>>]<<<[->>>+<<<]<+<<<<<<<<<]>>>>>>>>>
[>>>>[-<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
]>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>>>[-<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>]>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>++++++++
+++++++[[>>>>>>>>>]<<<<<<<<<-<<<<<<<<<[<<<<<<<<<]>>>>>>>>>-]+[>>>>>>>>[-<<<<<<<+
>>>>>>>]<<<<<<<[->>>>>>>+<<<<<<+<]>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>>>>>>[
-]>>>]<<<<<<<<<[<<<<<<<<<]>>>>+>[-<-<<<<+>>>>>]>[-<<<<<<[->>>>>+<++<<<<]>>>>>[-<
<<<<+>>>>>]<->+>]<[->+<]<<<<<[->>>>>+<<<<<]>>>>>>[-]<<<<<<+>>>>[-<<<<->>>>]+<<<<
[->>>>->>>>>[>>[-<<->>]+<<[->>->[-<<<+>>>]<<<[->>>+<<<<<<<<<<<<[<<<<<<<<<]>>>[-]
+>>>>>>[>>>>>>>>>]>+<]]+>>>[-<<<->>>]+<<<[->>>-<[-<<+>>]<<[->>+<<<<<<<<<<<[<<<<<
<<<<]>>>>[-]+>>>>>[>>>>>>>>>]>[-]+<]]+>[-<[>>>>>>>>>]<<<<<<<<]>>>>>>>>]<<<<<<<<<
[<<<<<<<<<]>>>>[-<<<<+>>>>]<<<<[->>>>+>>>>>[>+>>[-<<->>]<<[->>+<<]>>>>>>>>]<<<<<
<<<+<[>[->>>>>+<<<<[->>>>-<<<<<<<<<<<<<<+>>>>>>>>>>>[->>>+<<<]<]>[->>>-<<<<<<<<<
<<<<<+>>>>>>>>>>>]<<]>[->>>>+<<<[->>>-<<<<<<<<<<<<<<+>>>>>>>>>>>]<]>[->>>+<<<]<<
<<<<<<<<<<]>>>>[-]<<<<]>>>[-<<<+>>>]<<<[->>>+>>>>>>[>+>[-<->]<[->+<]>>>>>>>>]<<<
<<<<<+<[>[->>>>>+<<<[->>>-<<<<<<<<<<<<<<+>>>>>>>>>>[->>>>+<<<<]>]<[->>>>-<<<<<<<
<<<<<<<+>>>>>>>>>>]<]>>[->>>+<<<<[->>>>-<<<<<<<<<<<<<<+>>>>>>>>>>]>]<[->>>>+<<<<
]<<<<<<<<<<<]>>>>>>+<<<<<<]]>>>>[-<<<<+>>>>]<<<<[->>>>+>>>>>[>>>>>>>>>]<<<<<<<<<
[>[->>>>>+<<<<[->>>>-<<<<<<<<<<<<<<+>>>>>>>>>>>[->>>+<<<]<]>[->>>-<<<<<<<<<<<<<<
+>>>>>>>>>>>]<<]>[->>>>+<<<[->>>-<<<<<<<<<<<<<<+>>>>>>>>>>>]<]>[->>>+<<<]<<<<<<<
<<<<<]]>[-]>>[-]>[-]>>>>>[>>[-]>[-]>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>>>>>[-<
<<<+>>>>]<<<<[->>>>+<<<+<]>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>+++++++++++++++[
[>>>>>>>>>]+>[-]>[-]>[-]>[-]>[-]>[-]>[-]>[-]>[-]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>-]+
[>+>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>->>>>[-<<<<+>>>>]<<<<[->>>>+<<<<<[->>
[-<<+>>]<<[->>+>+<<<]+>>>>>>>>>]<<<<<<<<[<<<<<<<<<]]>>>>>>>>>[>>>>>>>>>]<<<<<<<<
<[>[->>>>>>>>>+<<<<<<<<<]<<<<<<<<<<]>[->>>>>>>>>+<<<<<<<<<]<+>>>>>>>>]<<<<<<<<<[
>[-]<->>>[-<<<+>[<->-<<<<<<<+>>>>>>>]<[->+<]>>>]<<[->>+<<]<+<<<<<<<<<]>>>>>>>>>[
>>>[-<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>]>
>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>[-]>>>>+++++++++++++++[[>>>>>>>>>]<<<<<<<<<-<<<<<
<<<<[<<<<<<<<<]>>>>>>>>>-]+[>>>[-<<<->>>]+<<<[->>>->[-<<<<+>>>>]<<<<[->>>>+<<<<<
<<<<<<<<[<<<<<<<<<]>>>>[-]+>>>>>[>>>>>>>>>]>+<]]+>>>>[-<<<<->>>>]+<<<<[->>>>-<[-
<<<+>>>]<<<[->>>+<<<<<<<<<<<<[<<<<<<<<<]>>>[-]+>>>>>>[>>>>>>>>>]>[-]+<]]+>[-<[>>
>>>>>>>]<<<<<<<<]>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>[-<<<+>>>]<<<[->>>+>>>>>>[>+>>>
[-<<<->>>]<<<[->>>+<<<]>>>>>>>>]<<<<<<<<+<[>[->+>[-<-<<<<<<<<<<+>>>>>>>>>>>>[-<<
+>>]<]>[-<<-<<<<<<<<<<+>>>>>>>>>>>>]<<<]>>[-<+>>[-<<-<<<<<<<<<<+>>>>>>>>>>>>]<]>
[-<<+>>]<<<<<<<<<<<<<]]>>>>[-<<<<+>>>>]<<<<[->>>>+>>>>>[>+>>[-<<->>]<<[->>+<<]>>
>>>>>>]<<<<<<<<+<[>[->+>>[-<<-<<<<<<<<<<+>>>>>>>>>>>[-<+>]>]<[-<-<<<<<<<<<<+>>>>
>>>>>>>]<<]>>>[-<<+>[-<-<<<<<<<<<<+>>>>>>>>>>>]>]<[-<+>]<<<<<<<<<<<<]>>>>>+<<<<<
]>>>>>>>>>[>>>[-]>[-]>[-]>>>>]<<<<<<<<<[<<<<<<<<<]>>>[-]>[-]>>>>>[>>>>>>>[-<<<<<
<+>>>>>>]<<<<<<[->>>>>>+<<<<+<<]>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>+>[-<-<<<<+>>>>
>]>>[-<<<<<<<[->>>>>+<++<<<<]>>>>>[-<<<<<+>>>>>]<->+>>]<<[->>+<<]<<<<<[->>>>>+<<
<<<]+>>>>[-<<<<->>>>]+<<<<[->>>>->>>>>[>>>[-<<<->>>]+<<<[->>>-<[-<<+>>]<<[->>+<<
<<<<<<<<<[<<<<<<<<<]>>>>[-]+>>>>>[>>>>>>>>>]>+<]]+>>[-<<->>]+<<[->>->[-<<<+>>>]<
<<[->>>+<<<<<<<<<<<<[<<<<<<<<<]>>>[-]+>>>>>>[>>>>>>>>>]>[-]+<]]+>[-<[>>>>>>>>>]<
<<<<<<<]>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>[-<<<+>>>]<<<[->>>+>>>>>>[>+>[-<->]<[->+
<]>>>>>>>>]<<<<<<<<+<[>[->>>>+<<[->>-<<<<<<<<<<<<<+>>>>>>>>>>[->>>+<<<]>]<[->>>-
<<<<<<<<<<<<<+>>>>>>>>>>]<]>>[->>+<<<[->>>-<<<<<<<<<<<<<+>>>>>>>>>>]>]<[->>>+<<<
]<<<<<<<<<<<]>>>>>[-]>>[-<<<<<<<+>>>>>>>]<<<<<<<[->>>>>>>+<<+<<<<<]]>>>>[-<<<<+>
>>>]<<<<[->>>>+>>>>>[>+>>[-<<->>]<<[->>+<<]>>>>>>>>]<<<<<<<<+<[>[->>>>+<<<[->>>-
<<<<<<<<<<<<<+>>>>>>>>>>>[->>+<<]<]>[->>-<<<<<<<<<<<<<+>>>>>>>>>>>]<<]>[->>>+<<[
->>-<<<<<<<<<<<<<+>>>>>>>>>>>]<]>[->>+<<]<<<<<<<<<<<<]]>>>>[-]<<<<]>>>>[-<<<<+>>
>>]<<<<[->>>>+>[-]>>[-<<<<<<<+>>>>>>>]<<<<<<<[->>>>>>>+<<+<<<<<]>>>>>>>>>[>>>>>>
>>>]<<<<<<<<<[>[->>>>+<<<[->>>-<<<<<<<<<<<<<+>>>>>>>>>>>[->>+<<]<]>[->>-<<<<<<<<
<<<<<+>>>>>>>>>>>]<<]>[->>>+<<[->>-<<<<<<<<<<<<<+>>>>>>>>>>>]<]>[->>+<<]<<<<<<<<
<<<<]]>>>>>>>>>[>>[-]>[-]>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>[-]>[-]>>>>>[>>>>>[-<<<<+
>>>>]<<<<[->>>>+<<<+<]>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>>>>>>[-<<<<<+>>>>>
]<<<<<[->>>>>+<<<+<<]>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>+++++++++++++++[[>>>>
>>>>>]+>[-]>[-]>[-]>[-]>[-]>[-]>[-]>[-]>[-]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>-]+[>+>>
>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>->>>>[-<<<<+>>>>]<<<<[->>>>+<<<<<[->>[-<<+
>>]<<[->>+>>+<<<<]+>>>>>>>>>]<<<<<<<<[<<<<<<<<<]]>>>>>>>>>[>>>>>>>>>]<<<<<<<<<[>
[->>>>>>>>>+<<<<<<<<<]<<<<<<<<<<]>[->>>>>>>>>+<<<<<<<<<]<+>>>>>>>>]<<<<<<<<<[>[-
]<->>>>[-<<<<+>[<->-<<<<<<+>>>>>>]<[->+<]>>>>]<<<[->>>+<<<]<+<<<<<<<<<]>>>>>>>>>
[>+>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>->>>>>[-<<<<<+>>>>>]<<<<<[->>>>>+<<<<
<<[->>>[-<<<+>>>]<<<[->>>+>+<<<<]+>>>>>>>>>]<<<<<<<<[<<<<<<<<<]]>>>>>>>>>[>>>>>>
>>>]<<<<<<<<<[>>[->>>>>>>>>+<<<<<<<<<]<<<<<<<<<<<]>>[->>>>>>>>>+<<<<<<<<<]<<+>>>
>>>>>]<<<<<<<<<[>[-]<->>>>[-<<<<+>[<->-<<<<<<+>>>>>>]<[->+<]>>>>]<<<[->>>+<<<]<+
<<<<<<<<<]>>>>>>>>>[>>>>[-<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>]>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>+++++++++++++++[[>>>>>>>>
>]<<<<<<<<<-<<<<<<<<<[<<<<<<<<<]>>>>>>>>>-]+>>>>>>>>>>>>>>>>>>>>>+<<<[<<<<<<<<<]
>>>>>>>>>[>>>[-<<<->>>]+<<<[->>>->[-<<<<+>>>>]<<<<[->>>>+<<<<<<<<<<<<<[<<<<<<<<<
]>>>>[-]+>>>>>[>>>>>>>>>]>+<]]+>>>>[-<<<<->>>>]+<<<<[->>>>-<[-<<<+>>>]<<<[->>>+<
<<<<<<<<<<<[<<<<<<<<<]>>>[-]+>>>>>>[>>>>>>>>>]>[-]+<]]+>[-<[>>>>>>>>>]<<<<<<<<]>
>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>->>[-<<<<+>>>>]<<<<[->>>>+<<[-]<<]>>]<<+>>>>[-<<<<
->>>>]+<<<<[->>>>-<<<<<<.>>]>>>>[-<<<<<<<.>>>>>>>]<<<[-]>[-]>[-]>[-]>[-]>[-]>>>[
>[-]>[-]>[-]>[-]>[-]>[-]>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>>>>>[-]>>>>]<<<<<<<<<
[<<<<<<<<<]>+++++++++++[-[->>>>>>>>>+<<<<<<<<<]>>>>>>>>>]>>>>+>>>>>>>>>+<<<<<<<<
<<<<<<[<<<<<<<<<]>>>>>>>[-<<<<<<<+>>>>>>>]<<<<<<<[->>>>>>>+[-]>>[>>>>>>>>>]<<<<<
<<<<[>>>>>>>[-<<<<<<+>>>>>>]<<<<<<[->>>>>>+<<<<<<<[<<<<<<<<<]>>>>>>>[-]+>>>]<<<<
<<<<<<]]>>>>>>>[-<<<<<<<+>>>>>>>]<<<<<<<[->>>>>>>+>>[>+>>>>[-<<<<->>>>]<<<<[->>>
>+<<<<]>>>>>>>>]<<+<<<<<<<[>>>>>[->>+<<]<<<<<<<<<<<<<<]>>>>>>>>>[>>>>>>>>>]<<<<<
<<<<[>[-]<->>>>>>>[-<<<<<<<+>[<->-<<<+>>>]<[->+<]>>>>>>>]<<<<<<[->>>>>>+<<<<<<]<
+<<<<<<<<<]>>>>>>>-<<<<[-]+<<<]+>>>>>>>[-<<<<<<<->>>>>>>]+<<<<<<<[->>>>>>>->>[>>
>>>[->>+<<]>>>>]<<<<<<<<<[>[-]<->>>>>>>[-<<<<<<<+>[<->-<<<+>>>]<[->+<]>>>>>>>]<<
<<<<[->>>>>>+<<<<<<]<+<<<<<<<<<]>+++++[-[->>>>>>>>>+<<<<<<<<<]>>>>>>>>>]>>>>+<<<
<<[<<<<<<<<<]>>>>>>>>>[>>>>>[-<<<<<->>>>>]+<<<<<[->>>>>->>[-<<<<<<<+>>>>>>>]<<<<
<<<[->>>>>>>+<<<<<<<<<<<<<<<<[<<<<<<<<<]>>>>[-]+>>>>>[>>>>>>>>>]>+<]]+>>>>>>>[-<
<<<<<<->>>>>>>]+<<<<<<<[->>>>>>>-<<[-<<<<<+>>>>>]<<<<<[->>>>>+<<<<<<<<<<<<<<[<<<
<<<<<<]>>>[-]+>>>>>>[>>>>>>>>>]>[-]+<]]+>[-<[>>>>>>>>>]<<<<<<<<]>>>>>>>>]<<<<<<<
<<[<<<<<<<<<]>>>>[-]<<<+++++[-[->>>>>>>>>+<<<<<<<<<]>>>>>>>>>]>>>>-<<<<<[<<<<<<<
<<]]>>>]<<<<.>>>>>>>>>>[>>>>>>[-]>>>]<<<<<<<<<[<<<<<<<<<]>++++++++++[-[->>>>>>>>
>+<<<<<<<<<]>>>>>>>>>]>>>>>+>>>>>>>>>+<<<<<<<<<<<<<<<[<<<<<<<<<]>>>>>>>>[-<<<<<<
<<+>>>>>>>>]<<<<<<<<[->>>>>>>>+[-]>[>>>>>>>>>]<<<<<<<<<[>>>>>>>>[-<<<<<<<+>>>>>>
>]<<<<<<<[->>>>>>>+<<<<<<<<[<<<<<<<<<]>>>>>>>>[-]+>>]<<<<<<<<<<]]>>>>>>>>[-<<<<<
<<<+>>>>>>>>]<<<<<<<<[->>>>>>>>+>[>+>>>>>[-<<<<<->>>>>]<<<<<[->>>>>+<<<<<]>>>>>>
>>]<+<<<<<<<<[>>>>>>[->>+<<]<<<<<<<<<<<<<<<]>>>>>>>>>[>>>>>>>>>]<<<<<<<<<[>[-]<-
>>>>>>>>[-<<<<<<<<+>[<->-<<+>>]<[->+<]>>>>>>>>]<<<<<<<[->>>>>>>+<<<<<<<]<+<<<<<<
<<<]>>>>>>>>-<<<<<[-]+<<<]+>>>>>>>>[-<<<<<<<<->>>>>>>>]+<<<<<<<<[->>>>>>>>->[>>>
>>>[->>+<<]>>>]<<<<<<<<<[>[-]<->>>>>>>>[-<<<<<<<<+>[<->-<<+>>]<[->+<]>>>>>>>>]<<
<<<<<[->>>>>>>+<<<<<<<]<+<<<<<<<<<]>+++++[-[->>>>>>>>>+<<<<<<<<<]>>>>>>>>>]>>>>>
+>>>>>>>>>>>>>>>>>>>>>>>>>>>+<<<<<<[<<<<<<<<<]>>>>>>>>>[>>>>>>[-<<<<<<->>>>>>]+<
<<<<<[->>>>>>->>[-<<<<<<<<+>>>>>>>>]<<<<<<<<[->>>>>>>>+<<<<<<<<<<<<<<<<<[<<<<<<<
<<]>>>>[-]+>>>>>[>>>>>>>>>]>+<]]+>>>>>>>>[-<<<<<<<<->>>>>>>>]+<<<<<<<<[->>>>>>>>
-<<[-<<<<<<+>>>>>>]<<<<<<[->>>>>>+<<<<<<<<<<<<<<<[<<<<<<<<<]>>>[-]+>>>>>>[>>>>>>
>>>]>[-]+<]]+>[-<[>>>>>>>>>]<<<<<<<<]>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>[-]<<<++++
+[-[->>>>>>>>>+<<<<<<<<<]>>>>>>>>>]>>>>>->>>>>>>>>>>>>>>>>>>>>>>>>>>-<<<<<<[<<<<
<<<<<]]>>>]
I don't understand why, but my program keeps getting stuck in some sort of endless loop. I try to debug it using gdb but it's hard to find the right breakpoint in order to see why it stuck.
The program is as follows:
#include <stdio.h>
#include <stdlib.h>
// Brainfuck instructions
// > Math stuff
#define INCR '+' // +1 on current MS
#define DECR '-' // -1 on current MS
// > Memory slot stuff
#define FORW '>' // Go to next MS
#define BACK '<' // Go to previous MS
// > Logic stuff
#define SJMP '[' // Loop till current MS value is equal to zero
#define EJMP ']' // Jump to the beginning of the loop
// > I/O stuff
#define PRTC '.' // Print character with MS value as ASCII code
#define GETC ',' // Get an user input ASCII character code
typedef unsigned char byte;
// The brainfuck program struct
typedef struct {
byte *values;
int size;
int index;
byte *loops_starts;
int loop_size;
int loop_index;
} BrainfuckProgram;
void initialize(BrainfuckProgram *bfp) {
bfp->values = malloc(bfp->size * sizeof(*bfp->values));
bfp->loops_starts = malloc(bfp->size * sizeof(*bfp->loops_starts));
}
int allocate_values(BrainfuckProgram *bfp) {
byte *newMem = realloc(bfp->values, bfp->size * sizeof(byte));
if (!newMem) {
return 1;
}
bfp->values = newMem;
return 0;
}
int allocate_new_loop(BrainfuckProgram *bfp) {
byte *newMem = realloc(bfp->loops_starts, bfp->loop_size * sizeof(byte));
if (!newMem) {
return 1;
}
bfp->loops_starts = newMem;
return 0;
}
void set_value(BrainfuckProgram *bfp, byte value) {
int tempValue = value < 0 ? 255: value % 256;
*(bfp->values + bfp->index) = tempValue;
}
int get_value(BrainfuckProgram *bfp) {
return *(bfp->values + bfp->index);
}
// FILE functions
int get_file_name(int argc, char *argv[], char** fname) {
if (argc == 1) {
printf("File name is missing\n");
return 1;
}
*fname = argv[1];
return 0;
}
int get_file_size(FILE *file) {
fseek(file, 0L, SEEK_END);
int size = ftell(file);
rewind(file);
return size;
}
// Main function
int main(int argc, char *argv[]) {
// Vector part
BrainfuckProgram bfp = {
.values = NULL,
.size = 1,
.index = 0,
.loops_starts = NULL,
.loop_index = 0,
.loop_size = 0
};
initialize(&bfp);
// FILE Part
char* fname = NULL;
int error = get_file_name(argc, argv, &fname);
if (error) {
goto exit;
}
// Create file variable
FILE *fin = NULL;
fin = fopen(fname, "r");
int size = get_file_size(fin);
// Create a char array of the right size
byte *prog = NULL;
prog = malloc(size * sizeof(*prog));
// Read 1 byte size times
fread(prog, 1, size, fin);
for (int i = 0; i < size; i++) {
byte current = *(prog+i);
switch (current) {
case INCR:
set_value(&bfp, get_value(&bfp) + 1);
break;
case DECR:
set_value(&bfp, get_value(&bfp) - 1);
break;
case FORW:
// if index+1 == size then we are at the
// last element of the vector cause
// size = index - 1
if (bfp.index+1 == bfp.size) {
bfp.size++;
int error = allocate_values(&bfp);
if (error) {
printf("an error occured while forwarding pointer");
goto close;
}
}
bfp.index++;
break;
case BACK:
// bfp.index == 0 then !bfp.index == true
if (!bfp.index) {
printf("can go back from index 0\n");
goto close;
}
bfp.index--;
break;
case SJMP:
if (bfp.loop_index == bfp.size) {
bfp.loop_size++;
int error = allocate_new_loop(&bfp);
if (error) {
printf("an error occured while forwarding pointer");
goto close;
}
}
bfp.loop_index++;
*(bfp.loops_starts + bfp.loop_index) = i;
break;
case EJMP:
if (bfp.loop_index == -1) {
printf("cannot go back");
goto close;
}
if (get_value(&bfp) != 0) {
i = *(bfp.loops_starts + bfp.loop_index);
} else {
bfp.loop_index--;
}
break;
case PRTC:
printf("%c", get_value(&bfp));
break;
case GETC:
; // Semicolon here because of the label error
byte buf;
scanf("%c", &buf);
set_value(&bfp, buf);
break;
}
}
close:
fclose(fin);
exit:
;
return 0;
}
I'd like to have some C related advice on what I have done wrong too.
The Mandelbrot program takes a decent time to run on a good interpreter. Yours, well, it isn't that good. That's why it "hangs" at the start.
Some good ideas that you had, performance-wise:
precalculating loops
Some bad ideas, performance-wise:
Using abstracted allocation functions instead of calling realloc
using scanf and printf instead of getchar and putchar
Some odd things that you did:
Manually truncating an unsigned char when wraparound is implicit
checking if an unsigned char is less than 0
using *(x + y) syntax instead of array indexing x[y]
I don't think you actually use those precalculated loops, if you do then probably not correctly
You also probably create a new precalculated loop every time you go over the loop again
Using the get_value and set_value functions instead of pointers (this will be a performance issue if you don't compile with optimizations)
A couple suggestions:
Try to avoid calling functions when you don't need to as much as possible.
Write a BrainFuck->C compiler using this reference.
On second thought, maybe you should try to debug this program instead.
You may also use my interpreter as a reference if you're OK with GPLv3. Note that it doesn't precalculate loops.

Struct memory allocation issues for message buffer

I'm trying to use static structs as a buffer for incoming messages, in order to avoid checking the buffer on the MCP2515-external unit. An ISR enters the function with a can_message* value 255 to actually read new messages from my MCP2515.
Other applications register an ID in the message passed as argument, in order to check if the buffer holds any messages with the same value.
This returns wrong IDs, and the rest of the datafields are 0 and uninitialized. What is wrong?
can_message struct:
typedef struct
{
uint8_t id;
uint8_t datalength;
uint8_t data[8];
}can_message;
int CAN_message_receive(can_message* message)
{
static volatile can_message* buffers = (volatile can_message*)0x18FF;
static int birth = 1;
if(birth)
{
for (int i; i < CAN_MESSAGE_UNIQUE_IDS; i++)
{
//These structs gets addresses outside SRAM
buffers[i] = (can_message){0,0,0};
}
birth = 0;
}
if (message == CAN_UPDATE_MESSAGES)
{
/* Sorts messages <3 */
can_message currentMessage;
//These functions are working:
CAN_message_get_from_MCP_buf(&currentMessage, 0);
buffers[currentMessage.id] = currentMessage;
CAN_message_get_from_MCP_buf(&currentMessage, 1);
buffers[currentMessage.id] = currentMessage;
return 0; //returns nothing !
}
if(buffers[message->id].id != 0)
{
printf("test\n");
//This copy gives wrong id and data:
memcpy(message, &buffers[message->id], sizeof(can_message));
buffers[message->id].id = 0;
return 0;
}
return -1;
}
Edit 1:
I did however notice that any buffers[i]-struct gets a totally different address than expected. It does not use the addresses following 0x18FF on the SRAM. Is there any way to change this?
Edit 2:
This is my main-loop:
while (1) {
//printf("tx buf ready: %d\n", MCP2515_TX_buf_empty(0));
//CAN_Loopback_test();
_delay_ms(500);
value = USART_ReadByte(0);
CAN_message_receive(&msg);
printf("CAN_receive: ID: %d, datalength: %d, data: \n",msg.id);
for (int k; k < msg.datalength; k++)
{
printf("%d, ",msg.data[k]);
}
printf("\n");
}
Edit 3: Changing the buffer-pointer to array solved the issue. (It does no longer use the SRAM, but whatever floats my boat)
int CAN_message_receive(can_message* message)
{
static can_message buffers[CAN_MESSAGE_UNIQUE_IDS];
static int birth = 1;
if(birth)
{
for (int i; i < CAN_MESSAGE_UNIQUE_IDS*10; i++)
{
*(char*)(0x18FF+i) = 0;
printf("buffers: %X\n", &buffers[i]);
}
birth = 0;
}
Solved!
Pointer to buffers changed to buffer-array:
int CAN_message_receive(can_message* message)
{
static can_message buffers[CAN_MESSAGE_UNIQUE_IDS];
static int birth = 1;
if(birth)
{
for (int i; i < CAN_MESSAGE_UNIQUE_IDS*10; i++)
{
*(char*)(0x18FF+i) = 0;
printf("buffers: %X\n", &buffers[i]);
}
birth = 0;
}
I would strongly suggest to decouple the ISR logic with the programs own message cache logic. Also the initializing logic with the birth variable looks unnecessary.
I would setup some ring buffer that the ISR can write messages to and from that the main code reads the data into the ID-lookup-buffer.
This would ensure that message updates does not interfere with readouts (at least if you check the read/write indices to your ring buffer) and also eliminates the need to put Mutexes around your whole message buffer.
Currently it smells very badly because of missing read/write synchronization.
// global
#define CAN_MESSAGE_UNIQUE_IDS 50
static can_message g_can_messagebuffers[CAN_MESSAGE_UNIQUE_IDS];
#define MAX_RECEIVEBUFFER 8
static volatile can_message g_can_ringbuffer[MAX_RECEIVEBUFFER];
static volatile int g_can_ringbufferRead = 0;
static volatile int g_can_ringbufferWrite = 0;
// called from ISR
void GetNewMessages()
{
// todo: check ring buffer overflow
can_message currentMessage;
CAN_message_get_from_MCP_buf(&g_can_ringbuffer[g_can_ringbufferWrite], 0);
g_can_ringbufferWrite = (g_can_ringbufferWrite + 1) % MAX_RECEIVEBUFFER;
CAN_message_get_from_MCP_buf(&g_can_ringbuffer[g_can_ringbufferWrite], 1);
g_can_ringbufferWrite = (g_can_ringbufferWrite + 1) % MAX_RECEIVEBUFFER;
}
// called from main loop
void handleNewMessages()
{
while(g_can_ringbufferRead != g_can_ringbufferWrite){
const can_message* currentMessage = &g_can_ringbuffer[g_can_ringbufferRead];
if(currentMessage->id < CAN_MESSAGE_UNIQUE_IDS)
{
g_can_messagebuffers[currentMessage->id] = *currentMessage;
}
g_can_ringbufferRead = (g_can_ringbufferRead + 1) % MAX_RECEIVEBUFFER;
}
}
// called from whoever wants to know
// todo:
// really required a by value interface?
// would it not be sufficient to return a pointer and
// provide an additional interface to mark the message as used?
int getMsg(can_message* message)
{
if(buffers[message->id].id != 0)
{
printf("test\n");
*message = &g_can_messagebuffers[message->id];
g_can_messagebuffers[message->id].id = 0;
return 0;
}
return -1;
}
// alternative to above
const can_message* getMsg(int id)
{
if( (id < CAN_MESSAGE_UNIQUE_IDS)
&& (g_can_messagebuffers[id] != 0))
{
return &g_can_messagebuffers[id].id;
}
return NULL;
}
void invalidateMsg(int id)
{
if(id < CAN_MESSAGE_UNIQUE_IDS)
{
g_can_messagebuffers[id] = 0;
}
}
edit:
after your changes to an message array instead some strange pointer, there is also no need for the setup routine for this code.
edit:
if your micro controller already has a buffer for received messages, then may be it is unnecessary at all to register a ISR and you could empty it from the mainloop directly into your own id-lookup buffer (assuming the mainloop is fast enough)

Initializing an array of structure in C

I'm using the LXLE 14.04 distribution of Linux. I want to write a C program to read commands, interpret and perform them. I'd like the program to be efficient, and I do not want to use a linked list. The commands are operations on sets. Each set can contain any of the values from 0 through 127 inclusive. I decided to represent a set as an array of characters, containing 128 bits. If bit at position pos is turned on then the number pos is in the set and if the bit at position pos is turned off then the number pos is not present in the set. For example, if the bit at position 4 is 1, then the number 4 is present in the set, if the bit at position 11 is 1 then the number 11 is present in the set.
The program should read commands and interpret them in a certain way. There are a few commands: read_set, print_set, union_set, intersect_set, sub_set and halt.
For example, the command read_set A,1,2,14,-1 in the terminal will cause the reading of values of the list into the specified set in the command. In this case the specified set in the command is A. The end of the list is represented by -1. So after writing this command, the set A will contain the elements 1,2,14.
This is what I have so far. Below is the file set.h
#include <stdio.h>
typedef struct
{
char array[16]; /*Takes 128 bits of storage*/
}set;
extern set A , B , C , D , E , F;
This is the file main.c
#include <stdio.h>
#include "set.h"
#include <string.h>
#include <stdlib.h>
set A , B , C , D , E , F; /*Variable definition*/
set sets[6];
/*Below I want to initialize sets so that set[0] = A set[1] = B etc*/
sets[0].array = A.array;
sets[1].array = B.array;
sets[2].array = C.array;
sets[3].array = D.array;
sets[4].array = E.array;
sets[5].array = F.array;
void read_set(set s,char all_command[])
{
int i, number = 0 , pos;
char* str_num = strtok(NULL,"A, ");
unsigned int flag = 1;
printf("I am in the function read_set right now\n");
while(str_num != NULL) /*without str_num != NULL get segmentation fault*/
{
number = atoi(str_num);
if(number == -1)
return;
printf("number%d ",number);
printf("str_num %c\n",*str_num);
i = number/8; /*Array index*/
pos = number%8; /*bit position*/
flag = flag << pos;
s.array[i] = s.array[i] | flag;
str_num = strtok(NULL, ", ");
if(s.array[i] & flag)
printf("Bit at position %d is turned on\n",pos);
else
printf("Bit at position %d is turned off\n",pos);
flag = 1;
}
}
typedef struct
{
char *command;
void (*func)(set,char*);
} entry;
entry chart[] = { {"read_set",&read_set} };
void (*getFunc(char *comm) ) (set,char*)
{
int i;
for(i=0; i<2; i++)
{
if( strcmp(chart[i].command,comm) == 0)
return chart[i].func;
}
return NULL;
}
int main()
{
#define PER_CMD 256
char all_comm[PER_CMD];
void (*ptr_one)(set,char*) = NULL;
char* comm; char* letter;
while( (strcmp(all_comm,"halt") != 0 ) & (all_comm != NULL))
{
printf("Please enter a command");
gets(all_comm);
comm = strtok(all_comm,", ");
ptr_one = getFunc(comm);
letter = strtok(NULL,",");
ptr_one(sets[*letter-'A'],all_comm);
all_comm[0] = '\0';
letter[0] = '\0';
}
return 0;
}
I defined a command structure called chart that has a command name and function pointer for each command. Then I have created an array of these
structures which can be matched within a loop.
In the main function, I've created a pointer called ptr_one. ptr_one holds the value of the proper function depending on the command entered by the user.
The problem is, that since user decides which set to use,I need to represent the sets as some variable, so that different sets can be sent to the function ptr_one. I thought about
creating an array in main.c like so
set sets[6];
sets[0] = A;
sets[1] = B;
sets[2] = C;
sets[3] = D;
sets[4] = E;
sets[5] = F;
And then call the function ptr_one in the main function like this ptr_one(sets[*letter-'A'] , all_command).
That way, I convert my character into a set.
The problem is that while writing the above code I got the following compile error:
error: expected ���=���, ���,���, ���;���, ���asm��� or ���attribute��� before ���.��� token
I also tried the following in the file main.c
sets[0].array = A.array;
sets[1].array = B.array;
sets[2].array = C.array;
sets[3].array = D.array;
sets[4].array = E.array;
sets[5].array = F.array;
But I got this compile error expected ���=���, ���,���, ���;���, ���asm��� or ���attribute��� before ���.��� token
I know similar questions have been asked, by they don't seem to help in my
specific case. I tired this set sets[6] = { {A.array},{B.array},{C.array},{D.array},{E.array},{F.array} } too but it did not compile.
What's my mistake and how can I initialize sets so that it holds the sets A though F?

Arduino Variable size Array Declaration

I get an error while trying to run the following code:
int SizeOfReadArray = 10;
int PacketLength = 5;
unsigned char rmessage[SizeOfReadArray];
unsigned long flag = 0;
unsigned char DataPacket[PacketLength];
int alternate = 1;
int remaining;
int Index;
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
}
void loop() {
PacketExtraction();
}
void PacketExtraction(){
// Read Serial Buffer store in array
Serial.readBytes(rmessage,SizeOfReadArray);
// onetime execution for getting exact message from serial buffer
if (flag == 0){
for (int j=0;j<SizeOfReadArray;j++){
// check for start of packets through header bytes
if (rmessage[j+0] == 65 && rmessage[j+1] == 65){
// store the Index for extracting packet from message array
Index = j;
remaining = SizeOfReadArray-Index+PacketLength;
flag = 1;
}
}
}
// actual packet extraction
/* take PacketLength of data from serial burffr and store the rest
for remaining bytes for next data packet construction */
if (alternate == 1){
for (int k=0;k<5;k++){
DataPacket[k]=rmessage[k+Index];
}
// storing remaining bytes form next execution
unsigned char previouspacket[remaining];
for (int k=0;k<remaining;k++){
previouspacket[k] = rmessage[k+Index+PacketLength];
}
alternate = 0;
}
/* now this time take the previously saved remaining bytes of packet
and merge them with the current packet data */
else{
for (int k=0;k<remaining;k++){
DataPacket[k] = previouspacket[k];
}
for (int k=0;k<(remaining+1);k++){
DataPacket[k+remaining] = rmessage[k];
}
alternate = 1;
}
}
Error Message:
Arduino: 1.6.1 (Windows 7), Board: "Arduino Mega or Mega 2560,
ATmega2560 (Mega 2560)"
sketch_apr04b.ino: In function 'void PacketExtraction()':
sketch_apr04b.ino:52:23: error: 'previouspacket' was not declared in
this scope
Error compiling.
This report would have more information with "Show verbose output
during compilation" enabled in File > Preferences.
previouspacket is only declared in the first branch of the if…then blocks.
You should move unsigned char previouspacket[remaining]; before the if statement

Resources