valgrind - Issues with memcheck in C calculator -


i'm writing calculator in c scratch (homework assignment) , have troubles memory somewhere.. algorithm works perfectly, i'm getting set of valgrind errors/warnings, e.g.:

echo -n "1" | valgrind ./a.out --track-origins=yes

==14261== conditional jump or move depends on uninitialised value(s) ==14261==    @ 0x400b9f: create_rpn (main.c:53) ==14261==    0x400742: main (main.c:253) 

my makefile:

all:     gcc main.c -g -o2 -wall -werror -std=c99 

my source code below (and on github). can it? thank in advance!

#include <stdio.h> #include <stdlib.h> #include <string.h>  #define max_len 1024  // needs check priority int get_power(char op) {     if (op == '+') {         return 2;     } else if (op == '-') {         return 2;     } else if (op == '*') {         return 4;     } else if (op == '/') {         return 4;     } else {         return 0;     } }   // checks if current char operator int is_operator(char op) {     if (op == '+' || op == '-' || op == '*' || op == '/') {         return 1;     } else {         return 0;     } }   // checks if current char digit int is_digit(char op) {     if ((op >= '0' && op <= '9') || op == '.') {         return 1;     } else {         return 0;     } }   // evaulates array in postfix double evaulate_rpn(char** exp, size_t len) {     double* stack = (double* ) malloc(len*sizeof(double)); // stack operands     double a1 = 0.0;     double a2 = 0.0;  // buffers save stack items     size_t place = 0; // current stack size     (size_t = 0; < len; ++i) {         if (is_operator(*exp[i]) == 1) {             // takes out last 2 operands, processes             if (place > 1) {                 a1 = stack[place - 2];                 a2 = stack[place - 1];                  if (strncmp(exp[i], "+", 1) == 0) {                     stack[place - 2] = a1 + a2;                 } else if (strncmp(exp[i], "-", 1) == 0) {                     stack[place - 2] = a1 - a2;                 } else if (strncmp(exp[i], "*", 1) == 0) {                     stack[place - 2] = a1 * a2;                 } else if (strncmp(exp[i], "/", 1) == 0) {                     stack[place - 2] = a1 / a2;                 }                 place -= 1;              } else if (place == 1) {                 // unary minus, unary plus..                 a1 = stack[place - 1];                  if (strncmp(exp[i], "-", 1) == 0) {                     stack[place - 1] = 0 - a1;                 } else if (strncmp(exp[i], "+", 1) == 0) {                     stack[place - 1] = a1;                 }              } else {                 // wrong order / else                 printf("[error]");                 exit(0);             }         } else {             // operand -> convert char double -> save double stack             stack[place] = atof(exp[i]);             place++ ;         }     }     float res = stack[0];     free(stack);     return res; // result here }   void push_to_stack(char*** reverse, size_t* inited_lines, size_t* used_lines, char* item, size_t size) {     if(*inited_lines <= *used_lines){         *inited_lines *= 2;         char** buf = (char** ) realloc(*reverse, (*inited_lines)*sizeof(char** ));         if (buf) {             *reverse = buf;         } else {             printf("[error]");             exit(0);         }     }     char* str = calloc(size + 1, sizeof(char));     if (str) {         memcpy(str, item, size + 1);         str[size] = '\0';          (*reverse)[*used_lines] = str;         (*used_lines)++ ;     } else {         printf("[error]");         exit(0);     } }   // transform infix postfix notation double create_rpn(char* exp, size_t len){      // stack of chars operands ()+-*/     char* stack = (char* ) malloc(len);     if (stack == null) {         printf("[error]");         exit(0);     }     size_t stack_top = 0;  // position of last item in stack      // array of numbers     size_t inited_lines = 1;     size_t used_lines = 0;     char** reverse = (char** ) malloc(inited_lines*sizeof(char* ));     if (reverse == null) {         printf("[error]");         exit(0);     }      char buffer = 0;     int bracket_deep = 0;     int digit = 0; // flag start parsing numbers/digits     size_t start_index = 0; // parsing long-vals     size_t index = 0;     while (index <= len) {         buffer = exp[index];  // buffer constats 1 char string         if (is_digit(buffer) == 1) {             // save first digit place             if (digit == 0) {                 start_index = index;                 digit = 1;             }         } else {             // push stack when num on             if (digit == 1) {                 digit = 0;                 size_t size = index - start_index; // size of str                 push_to_stack(&reverse, &inited_lines, &used_lines, exp + start_index, size);             }              // push operands + check priority             if (is_operator(buffer) == 1) {                 size_t power = get_power(buffer);                 (int = stack_top - 1; >= 0; --i) {                     if (stack[i] == '(') {                         break;                     }                     if (get_power(stack[i]) >= power) {                         push_to_stack(&reverse, &inited_lines, &used_lines, &stack[i], 1);                         stack_top-- ;                     }                 }                 // push current operand stack                 stack[stack_top++ ] = buffer;              } else if (buffer == '(') {                 stack[stack_top++ ] = buffer;                 bracket_deep++ ;              } else if (buffer == ')') {                 // push operands result                 bracket_deep-- ;                 stack_top-- ; // if no, '' added output                 while (stack[stack_top] != '(') {                     push_to_stack(&reverse, &inited_lines, &used_lines, &stack[stack_top], 1);                     if (stack_top > 0) {                         stack_top-- ;                     } else {                         break;                     }                 }             } else if (buffer == ' ' || buffer == '\n') {                 // ignore case              } else if (buffer == '\0') {                 (int = stack_top - 1; >= 0; --i) {                     push_to_stack(&reverse, &inited_lines, &used_lines, &stack[i], 1);                 }                 stack_top = 0;             } else {                 printf("[error]"); // - wrong char: '%s', %c\n", buffer, *buffer); // wrong char!                 exit(0);             }         }         if (bracket_deep < 0) {             printf("[error]"); // wrong bracket expr             exit(0);         }         index++ ;     }     free(stack);      if (bracket_deep == 0) {         double res = evaulate_rpn(reverse, used_lines);         (int = 0; < inited_lines; i++) {             free(reverse[i]);         }         free(reverse);         return res;     } else {         printf("[error]");  // wrong brackets         exit(0);     } }   int main() {     char* expression = (char* ) malloc(max_len*sizeof(char));     if (expression) {         size_t len = 0;         while (scanf("%c", &expression[len]) != -1) {   // switch getch ???             if (expression[len] != ' ') {   // save except spaces                 len++ ;             }         }         double result = create_rpn(expression, len);         printf("%.2f", result);         free(expression);     } else {         printf("[error]");         exit(0);     }     return 0; } 

you reading 1 byte beyond array bound, because while loop in create_rpn() is

while (index <= len) 

but should be

while (index < len)    /*         ^ without = */ 

since arrays 0 indexed, exp[len] beyond array.

also

  1. avoid redundant parentheses, make code ugly , hence, hard read , understand.

  2. do not cast return value of malloc(), read link , understand why.

  3. another tip make code clearer, avoid mixing code declarations, compiler it's easy see variable's scope, not eyes.


Comments

Popular posts from this blog

asp.net mvc - SSO between MVCForum and Umbraco7 -

Python Tkinter keyboard using bind -

ubuntu - Selenium Node Not Connecting to Hub, Not Opening Port -