1

I need help implementing my code. Here is the code in C. My assignment is to create a program for reverse polish notation. Here is what I have so far. Several Errors I see are "EXE_BAD_ACCESS(code=1, address=0x32)" Any help would be of great use.

#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <string.h>

typedef struct node
{
    int datum;
    int isOperator;
    struct node* left;
    struct node* right;
}*Node;

Node BuildTree(char** argv, int* index);
int isOperator(char ch);
int isadd(int);
int evaluate(Node);
void infix(Node, int);

int main(int argc, char* argv[])
{
    int i = 9; //argc - 1;
    Node tree = NULL;

    char* debugList[] = {NULL,"2","9","+","5","-", "6", "D", "3", "X"};

    tree = BuildTree(debugList, & i);
    infix(tree, 43);

    printf("\n%d", evaluate(tree));
    return 0;
}

Node BuildTree(char** argv, int* index)
{
    Node node;
    if (*index < 1)
        return NULL;

    if(isOperator(argv[*index][0]))
    {
        //insert to the right
        node = (Node) malloc(sizeof(Node));
        node -> datum = (int) argv[*index][0];
        (*index)--;
        node -> right = BuildTree(argv, index);
        node -> left = BuildTree(argv, index);
        node -> isOperator = 1;
        return node;
    }
    else
    {
        node = (Node) malloc(sizeof(Node));
        node -> right = NULL;
        node -> left = NULL;
        node -> datum = (int) argv[*index][0];
        node -> isOperator = 0;
        (*index)--;
        return node;
    }
}
// Return true if ch is a operator, otherwise false
int isOperator(char ch)
{
    if (ch == '+' || ch == '-' || ch == 'D' || ch == 'X')
        return 1;

    else
        return 0;
}

void infix(Node node, int c){
    if(node == NULL)
        return;
    else if (isadd(node -> datum) && !isadd(c)){
        printf("(");
        infix(node -> left, node -> datum);
        printf("%c", (char) node -> datum);
        infix(node -> right, node -> datum);
        printf(")");
    }
    else {
        infix(node -> left, node -> datum);
        printf("%c", (char) node -> datum);
        infix(node -> right, node -> datum);
    }
}

int isadd(int c)
{
    if(c == 43 || c == 45)
        return 1;
    else
        return 0;
}

int evaluate(Node node)
{
    if(node -> isOperator)
    {
        switch(node -> datum)
        {
            case 43:
                return evaluate(node -> left) + evaluate(node -> right);
            case 45:
                return evaluate(node -> left) - evaluate(node -> right);
            case 68:
                return evaluate(node -> left) / evaluate(node -> right);
            case 88:
                return evaluate(node -> left) * evaluate(node -> right);
            default :
                return -1;
        }
    }else{
        return node -> datum - 48;
    }
}

The portion I'm getting errors in are here.

int main(int argc, char* argv[])
{
    int i = 9; //argc - 1;
    Node tree = NULL;

    char* debugList[] = {NULL,"2","9","+","5","-", "6", "D", "3", "X"};

    tree = BuildTree(debugList, & i);
    infix(tree, 43);    //EXE_BAD_ACCESS(code=1, address=0x32)

    printf("\n%d", evaluate(tree));
    return 0;
}

And here.

void infix(Node node, int c){
    if(node == NULL)
        return;
    else if (isadd(node -> datum) && !isadd(c)){     //EXE_BAD_ACCESS(code=1, address=0x32)
        printf("(");
        infix(node -> left, node -> datum);          //EXE_BAD_ACCESS(code=1, address=0x32)
        printf("%c", (char) node -> datum);
        infix(node -> right, node -> datum);         //EXE_BAD_ACCESS(code=1, address=0x32)
        printf(")");
    }
    else {
        infix(node -> left, node -> datum);          //EXE_BAD_ACCESS(code=1, address=0x32)
        printf("%c", (char) node -> datum);
        infix(node -> right, node -> datum);         //EXE_BAD_ACCESS(code=1, address=0x32)
    }
}
Yu Hao
  • 119,891
  • 44
  • 235
  • 294
justjoe
  • 11
  • 1
  • 2
  • 2
    On an unrelated note, don't use "magic numbers" in your code, they will be hard to understand for other people and even yourself in a couple of weeks time. Since you are using the ASCII code, why not use the actual character literal instead? Like `'+'` instead of `43`. This also have the benefit that it will work on systems that doesn't use ASCII encoded characters (even if they are few and you're unlikely to ever come close to one). – Some programmer dude Dec 08 '14 at 10:21
  • 1
    As for your problem, I recommend you to stop making type-aliases of pointers. That will make errors like you have here harder to make, and also make the code much more easy to read and understand. – Some programmer dude Dec 08 '14 at 10:28

1 Answers1

4

in your code, change

node = (Node) malloc(sizeof(Node));

to

node = malloc(sizeof(struct node));

Node is of type struct node *.

Hoewver, as pointer out by @WhozCraig, the most portable and robust version of this code should be

node = malloc(sizeof *node);
Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
  • Note: `malloc(sizeof *node)` is equally effective and arguably preferable as it pins the malloc to the size of the target pointer; not the size of some type that may someday be unrelated. Either way, This answer is correct, and also quietly points out by example the preference of [*not* casting `malloc` in C programs](http://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc) – WhozCraig Dec 08 '14 at 10:24
  • @WhozCraig right sir, will update my answer accordingly. – Sourav Ghosh Dec 08 '14 at 10:25