'Empty tree' function causing program to crash - c

I have a empty_tree() function that basically returns a true value if the tree is empty and returns false if it is not.
bool empty_tree(AVL self)
{
if (self == NULL)
{
return true;
}
else
{
return false;
}
}
It exists so that my program is easier to understand without comments. Now, it works fine everywhere else in my program. However when I try and use it in my insert function in place of the working:
if(self == NULL)
my program will crash. This isn't really a big deal and using the 'if (self==NULL) will suffice, but I was just wondering if anyone had any ideas as to why this would cause the program to crash. As I said, it's not extremely important so I won't bother including more code, but if anyone had any guesses, I'd appreciate hearing your thoughts.
EDIT: Upon request, here's where the section that works:
if (self == NULL)
{
self = (AVL)malloc(sizeof(struct avlNode));
self->student_id = id;
self->left = self->right = NULL;
}
And here's the code that will, when changed to this, crash the program:
if (!empty_tree(self))
{
self = (AVL)malloc(sizeof(struct avlNode));
self->student_id = id;
self->left = self->right = NULL;
}

Related

Passing a void (*fn) from a class

I'm writing an auto display turn-off function with ESP32 on Arduino framework with PIO.
I have a Screen class for handling all of the screen functions.
void Screen::turn_off_screen(){
digitalWrite(SCREEN_ENABLE, LOW);
}
void turn_off_screen_wrapper()
{
Serial.println("turn_off_screen_wrapper called");
if (c_screen_Instance != nullptr)
{
c_screen_Instance->turn_off_screen();
}
}
void Screen::auto_display_power_off(int timeout){
Serial.println("auto_display_power_off called");
c_screen_Instance = this;
auto_off_timer = timerBegin(0, 80, true);
Serial.println("auto_off_timer ran");
timerAttachInterrupt(auto_off_timer, &turn_off_screen_wrapper, true);
Serial.println("timerAttachInterrupt ran");
//Converts given seconds from us to seconds
timerAlarmWrite(auto_off_timer,timeout*1000000,false);
timerAlarmEnable(auto_off_timer);
}
The code compiles however I get this when I run it on the board.
auto_display_power_off called
[E][esp32-hal-cpu.c:93] addApbChangeCallback(): duplicate func=400811F8 arg=3FFBDC54
auto_off_timer ran
The screen never gets turned off of course since the callback never runs. Any ideas why this is happening?
is c_screen_Instance global?
is auto_off_timer global?
Consider providing a bit more of your code.
But anyway.
bool addApbChangeCallback(void * arg, apb_change_cb_t cb){
initApbChangeCallback();
apb_change_t * c = (apb_change_t*)malloc(sizeof(apb_change_t));
if(!c){
log_e("Callback Object Malloc Failed");
return false;
}
c->next = NULL;
c->prev = NULL;
c->arg = arg;
c->cb = cb;
xSemaphoreTake(apb_change_lock, portMAX_DELAY);
if(apb_change_callbacks == NULL){
apb_change_callbacks = c;
} else {
apb_change_t * r = apb_change_callbacks;
// look for duplicate callbacks
while( (r != NULL ) && !((r->cb == cb) && ( r->arg == arg))) r = r->next;
if (r) {
log_e("duplicate func=%8p arg=%8p",c->cb,c->arg);
free(c);
xSemaphoreGive(apb_change_lock);
return false;
}
else {
c->next = apb_change_callbacks;
apb_change_callbacks-> prev = c;
apb_change_callbacks = c;
}
}
xSemaphoreGive(apb_change_lock);
return true;
}
This is addApbChangeCallback's declaration.
Your error comes from this line :
while( (r != NULL ) && !((r->cb == cb) && ( r->arg == arg))) r = r->next;
Where r it's a struct to hold all the callbacks.
This error indeed indicates this callback function was already assigned somewhere in your code. r is global, so your code is re-assigning the same callback twice.
Try to either only assign it once, or to unassign the function before assigning it again with removeApbChangeCallback(void * arg, apb_change_cb_t cb) or timerDetachInterrupt
I've also found a reported issue related to timerAttach on the current version here: https://github.com/espressif/arduino-esp32/issues/6730
Try to roll back the Platform PIO's version to a more stable one:
# instead of espressif32
platform = https://github.com/platformio/platform-espressif32.git#<tag-version>
Check on the git link for the available tags you can use.
Problem was that I was attaching the interrupt in the void loop(). Which would run way faster than the actual timer. After moving it to setup (Setup being a placeholder) I plan on having it on a Hardware interrupt it worked as expected.

List data type error in listInsertLast?

I had a homework where I should implement a list data type in C, done everything but the tests that the tutors gave us, aren't passing correctly, here you go (I'll explain what wrong in a min):
#define ASSERT_TEST(b) do { \
if (!(b)) { \
printf("\nAssertion failed at %s:%d %s\n",__FILE__,__LINE__,#b); \
return false; \
} \
} while (0)
the tests failing are:
after I create a list with 4 elements in it using listInsertLast, and I use this:
ASSERT_TEST(LIST_INVALID_CURRENT == listRemoveCurrent(list));
and after I create another list with 4 elements using listInsertLast and I use this:
ASSERT_TEST(listGetNext(list2) == NULL);
NOTE: I use these lines immediately after creating the list to check if the inner iterator status haven't changed after listInsertLast function, the thing is they should work, and the value returned by these 2 lines should be correct ( LIST_INVALID_CURRENT is enum value).. but they're not working, now I assume it's something that has to do with listInsertLast, they told us in the assignment we shouldn't change the inner iterator after adding at the end of the list, I tried everything possible, but still cant get them to work, my listInsertLast:
ListResult listInsertLast(List list, ListElement element) {
if (!list || !element) {
return LIST_NULL_ARGUMENT;
}
Node newElement = malloc(sizeof(*newElement));
if (!newElement) {
return LIST_OUT_OF_MEMORY;
}
newElement->data = list->copyElement(element);
if (listGetSize(list) > 0) {
Node save_iter = list->iter; // here?
list->iter = list->first;
while (list->iter->next) {
list->iter = list->iter->next;
}
list->iter->next = newElement;
list->iter = list->iter->next;
list->iter->next = NULL;
list->iter = save_iter; // and here ?
} else {
list->first = newElement;
list->first->next = NULL;
list->iter = list->first; // or maybe here ?
}
list->size++;
return LIST_SUCCESS;
}
What could the problem be, or if it has to do with other thing please help me..
Thank you very much <3

Apparently allocating memory and freeing it properly but program still crashes

So I've got a weird problem and can't seem to solve it. I have an ADT called TEAM:
typedef struct Team {
char *name;
int points;
int matches_won;
int goal_difference;
int goals_for;
}TEAM;
I created a function to initialize variables of the TEAM* type with a given name:
TEAM *createTEAM (char *name){
int error_code;
if (name != NULL){
if(strcmp(name, "") != 0){
TEAM *new_team = (TEAM*)malloc(sizeof(TEAM));
new_team->name = (char*)malloc(sizeof(char)*strlen(name));
strcpy(new_team->name, name);
new_team->points = 0;
new_team->matches_won = 0;
new_team->goal_difference = 0;
new_team->goals_for = 0;
return new_team;
}else{
error_code = EMPTY_STRING_CODE;
}
} else {
error_code = NULL_STRING_CODE;
}
printf("Erro ao criar time.\n");
printError(error_code);
return NULL;
}
I also created a function to delete one of these TEAM* variables properly:
void deleteTEAM (TEAM *team_to_remove){
free(team_to_remove->name);
team_to_remove->name = NULL;
free(team_to_remove);
team_to_remove = NULL;
}
But when one or multiple test functions that I created (example below) run, the program sometimes crashes, sometimes doesn't. I've noticed that changing the names I use affects whether it crashes or not, even if they don't affect the test results.
int create_team_01(){
int test_result;
TEAM *Teste = createTEAM("Cruzeiro");
if (strcmp(Teste->name, "Cruzeiro") == 0){
test_result = TRUE;
}else test_result = FALSE;
_assert(test_result); //just a macro function that will check the argument and return 1 if it's false
deleteTEAM(Teste);
return 0;
}
I don't see any problems with memory allocation or freeing. Still, the debugger complains a lot about the first free() (can't find bounds) of the deleteTEAM function. Any ideas? Thanks a lot in advance for any help.
P.S.: I've even tried checking the mallocs' results, but it doesn't seem to be the problem either, so I removed it for the sake of simplicity.

Mysterious change of value in pointer vector

As homework I have to implement a function that receives two vectors of pointers. It should compare the values contained in the memory address pointed by these pointers and return TRUE or FALSE if they are all the same or not.
For this I have created this function:
tBoolean comparePointerVector(int *v1[], int *v2[]) {
int i;
tBoolean status = TRUE;
for (i=0;i<MAX_DELIVERIES;i++) {
if(*v1[i]!=*v2[i]) {
status = FALSE;
break;
}
}
return status;
}
The method compiles fine but always crashes in the first iteration. Investigating the problem I have found a very strange phenomena. Adding the next code before entering the for loop, the printed results for both lines are different, which is very surprising for me:
printf("value %d\n ",*v1[0]);
printf("value %d\n ",*v1[0]);
The first line prints correctly the value pointed by v1[0], but the second line prints the memory address. How is this possible that the they don't print the same?
Besides this why this code seems to break my program?
*v1[i]!=*v2[i]
I ask here in the same question because I think both questions are related.
EDIT:
Definition of MAX_DELIVERIES in a file called data.h
#define MAX_DELIVERIES 50
Calling the function:
tBoolean pd_equals(tProductDeliveries pd1, tProductDeliveries pd2){
//For maintenability and better understading this method contains several 'return' statements.
if(pd1.poductID!=pd2.poductID) {
return FALSE;
} else if(pd1.totalPurchases!=pd2.totalPurchases) {
return FALSE;
} else if(pd1.totalSales!=pd2.totalSales) {
return FALSE;
} else if(pd1.total!=pd2.total) {
return FALSE;
} else if(comparePointerVector(pd1.sales, pd2.sales) != TRUE) {
return FALSE;
} else if(comparePointerVector(pd1.purchases, pd2.purchases) != TRUE) {
return FALSE;
}
return TRUE;
}
Calling the pd_equals method:
pd_getProductDeliveries(deliveries, 123, &pd1);
if(pd_equals(pd1, pd1)==TRUE) {
printf("\n\t-> OK\n");
passedTest[0]++;
} else {
printf("\n\t-> FAIL.\n");
}
Thanks everybody for your answers. I got it fixed but now I am even more puzzled.
I just have removed the system("PAUSE"); I had between the two printf and now both print exactly the same. I am sorry I didn't post it in my code but I thought it was totally irrelevant.
Now my next question would be: What in the world is the system("PAUSE") doing that messes up the memory?
I think the issue is caused by the comparison if(*v1[i]!=*v2[i]). It must be
v1[i] != v2[i] or *(v1+i) != *(v2+i)

Different outputs from the same C program

i have a pointer problem:
SearchResults* pointy;
pointy = returnResults();
if(pointy != NULL && pointy->results[0] != NULL)
{
HandleResponse();
printf("sharp");
}else{
//do other things
}
if(pointy == NULL){
printf("blunt");
}
if(pointy->results[0] == NULL){
printf("wah!!!");
}
in the debugger the code correctly works and i get "sharp" but under the same conditions in the bash terminal i get "wah!!!"
typedef struct SearchResults
{
TreeNode* results[40];
int searchIndex;
} SearchResults;
SearchResults* lostAndFound;
SearchResults* returnResults()
{
return lostAndFound;
}
Found a Problem in both the debug and release variations there is a .csv file.. the debug reads and writes to it perfectly fine whereas the release seems to steamroll it into nothigness.

Resources