strcat 时的未定义行为

undefined behavior when strcat

in = "(A + B) * C - D * F + C";
#define MAXL 256

我在 case ')' 的代码有问题。

我的代码未完成,因为它在某处遗漏了几行代码以将堆栈中的所有最终 char = operators 添加到 tempExp,我可能很快就会弄清楚™。我现在需要的是您输入为什么此行 while(c[0] != '(') strcat(tempExp, c); 会导致未定义的行为。

非常感谢!

注意:出现这段乱码的原因 c[0] = *((char*)pop(s)) 是 pop returns a void* 出于本练习的目的我无法更改它。

void convertIntoPost(char * in, char ** out)
{
    int i;
    Stack * s = createStack();
    char tempExp[MAXL] = "temp: ", c[2];
    c[1] = '[=11=]';
    printf("\n%s\n", tempExp);
    for(i = 0; i <= strlen(in); ++i)
    {
        printf("i: %d", i);
        c[0] = in[i];
        if(isalpha(c[0]) || isalnum(c[0]))
        {
            c[0] = in[i];
            printf("\nc passed isalpha OR isalnum: %s\n", c);
            strcat(tempExp, c);
        }
        else
        {
            switch(in[i])
            {
                case ' ' : break;
                case '(' :
                    push(s, &in[i]);
                    break;
                case ')' :
                    c[0] = *((char*)pop(s));
                    printf("c in case ')': %s", c); /* Show expected result */
                    printf("\n%s", tempExp); /* Just checking tempExp and see no problem */
                    while(c[0] != '(')
                        strcat(tempExp, c);
                    printf("\n%s", tempExp); /* Program stopped before it gets here */
                    break;
                default :
                    while(!isEmpty(s) && (priority(in[i]) <= priority(c[0] = *((char*)pop(s)))))
                        strcat(tempExp, c);
                    push(s, &in[i]);
            }               
        }            
    }
    printf("\nThis is in: %s", in);
    printf("\n%s", tempExp);
    *out = (char*)malloc(strlen(tempExp) + 1);
    *out = strdup(tempExp);
    makeEmpty(s);
}

int priority(char c)
{
    if(c == '(')
        return(0);
    else if(c == '+' || c == '-')
        return(1);
    else if(c == '*' || c == '/')
        return(2);
}

循环

while(c[0] != '(')
   strcat(tempExp, c);

将 运行 无限期地(假设 c[0] 不是 '('),超过 运行 字符串的大小(256 个字符),因为它会不断添加相同的字符串(c) 到 tempExp 上。这会导致无数的错误,但通常是堆栈溢出或缓冲区溢出......只有在到达字符串末尾 (256) 时才会出现未定义的行为,从那时起它就会不优雅地崩溃

除了 Grantly 指出的无限循环之外,您还有其他几个问题,主要是因为两件事:

  1. 您的循环包含 in 的字符串终止符,因此您将在 switch 语句的默认情况下结束,实际上您将调用 priority('[= 12=]') 这会导致你的第二个问题。您还将使用指向字符串终止符的指针调用 push,如果 push 假定指针不指向字符串的末尾,您也可能在那里遇到问题。

  2. 第二个问题是 priority 函数,因为它没有 return 导致 未定义行为的所有分支的值 如果您传递了条件中不期望的字符(例如字符串终止符)。您需要添加一个明确的 else 子句。