char expr2[SIZE], expr3[SIZE]; と宣言されたら、
expr2[0]~expr2[SIZE-1] の SIZE個の要素しか参照できません。
expr2[SIZE] = expr3[SIZE]; は範囲外アクセスです。
atoi に渡す文字列は '\0' で終了していなければなりません。
atoi(expr2) の expr2 に入っている数字列は '\0' で終了していません。
atoi呼出しの直前に expr2[t] = '\0'; が必要でしょう。
数字を見つけたら、そこで数字が続く限り、それを expr2 にため込んで
atoi を呼び出せばよいでしょう。他の演算子で処理しなくて済みます。
コード:
for (i = 0; i < k; i++) {
if (expr[i] <= '9' && expr[i] >= '0') {
t = 0;
do {
expr2[t++] = expr[i++];
} while (expr[i] <= '9' && expr[i] >= '0');
expr2[t] = '\0';
push(atoi(expr2));
i--;
}
else if (expr[i] == a) push(pop() + pop());
else if (expr[i] == s) x = pop(), push(pop() - x);
else if (expr[i] == m) push(pop() * pop());
else if (expr[i] == d) {
x = pop(), y = pop();
if (x == 0) printf("計算できません。(%d ÷ %d)\n", y, x);
else push(y / x);
}
else if (expr[i] != w) printf("不正な操作です。\n");
}
atoi の代わりに strtol を使えば、数字列の終わりの位置が分かります。
expr2 は不要です。
コード:
if (expr[i] <= '9' && expr[i] >= '0') {
char *p;
push(strtol(expr + i, &p, 10));
i = p - expr - 1;
}