-4

This is a parentheses balanced code. I submitted and got comment from my professor.

"Your stack is supposed to grow and shrink dynamically to accommodate any number of characters. DO NOT USE scanf for %s, this is risky behavior and Dr. Adams does not approve. Write a helper function to read in characters until newline."

Can you help me to fix this problem?

kimchistudent
  • 97
  • 2
  • 7
  • Your TA is 100% correct. You are unsafely reading into a memory area that is of one byte in size. You neither account for the trailing NULL that will be added since you are using %s nor do you account for input longer than one character. You could follow your TAs advice and create a helper function with a loop that reads one character at a time, adding it to a dynamically sized array, until a newline is encountered. – David Hoelzer Mar 27 '16 at 23:53
  • For completeness, please post the stack implementation. – chqrlie Mar 28 '16 at 00:11

1 Answers1

1

Your professor is correct and he gave you the solution: do not read a line into a buffer with scanf("%s",...): an arbitrary long line will cause a buffer overflow. You do not need to read a full line, just make check_balanced read one character at a time:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "stack.h"

#define TRUE  1
#define FALSE 0

int check_matching(void);

int main(int argc, char *argv[]) {
    int n, i, c;
    /* get the number of cases */
    if (scanf("%d", &n) != 1) {
        printf("invalid number\n");
        exit(1);
    }
    /* consume the rest of the line */
    while ((c = getchar()) != EOF && c != '\n')
        continue;

    for (i = 0; i < n; i++) {
        if (check_matching()) {
            printf("yes\n");
        } else {
            printf("no\n");
        }
    }
    return 0;
}

int check_matching(void) {
    int ret = TRUE, symbol, checkSymbol;
    LinkedStack *pStack;
    StackNode *pNode;
    StackNode node;

    pStack = createLinkedStack();
    if (pStack == NULL) {
        printf("createLinkedStack failed\n");
        exit(1);
    }

    /* read a full line, one byte at a time */
    while ((symbol = getchar()) != EOF && symbol != '\n') {
        if (ret == FALSE)
            continue;
        switch (symbol) {
        case '(':
        case '[':
        case '{':
            node.data = symbol;
            pushLS(pStack, node);
            break;

        case ')':
        case ']':
        case '}':
            pNode = popLS(pStack);
            if (pNode == NULL) {
                ret = FALSE;
                break;
            } else {
                checkSymbol = pNode->data;

                if ((symbol == ')' && checkSymbol == '(')
                ||  (symbol == ']' && checkSymbol == '[')
                ||  (symbol == '}' && checkSymbol == '{')) {
                    // Right case. do nothing.
                } else {
                    ret = FALSE;
                }
                free(pNode);
            }
            break;
        }
    }

    if (isLinkedStackEmpty(pStack) == FALSE) {
        ret = FALSE;
    }
    deleteLinkedStack(pStack);
    return ret;
}
chqrlie
  • 131,814
  • 10
  • 121
  • 189