首页 > 解决方案 > 如何解决我的代码中的分段错误。?

问题描述

我正在尝试解决括号匹配的问题,即给定一系列左括号和右括号exp,由 (or )、方括号 []或大括号}or组成{,我需要判断给定的序列是否平衡。

Sample Input1:
exp = "[]{}()"

Sample Output1:
Match Successfull....!


----------


Sample Input2:
exp = "[]{(]}()"

Sample Output1:
Match not Successfull....!

PS:空字符串被认为是平衡字符串。
下面是用 C 编写的代码,我尝试使用struct. 我实现了堆栈的所有必要功能,即 ,pop()push()isFull()但是
,我遇到了分段错误。请帮我纠正错误。

#include <stdio.h>
#include <stdlib.h>
struct stack {
    int size;
    int top;
    char *arr;
};

int isEmpty(struct stack *ptr) {
    if (ptr->top == -1)
    {
        return 1;
    }
    return 0;
}

int isFull(struct stack *ptr) {
    if (ptr->top == ptr->size - 1)
    {
        return 1;
    }
    return 0;
}

int push(struct stack *ptr, char val) {
    if (isFull(ptr))
    {
        return 1;
    }
    else
    {
        ptr->top++;
        ptr->arr[ptr->top] = val;
    }
}

int pop(struct stack *ptr) {
    char val;
    if (isEmpty(ptr))
    {
        return 1;
    }
    else
    {
        ptr->top--;
        val = ptr->arr[ptr->top];
        return val;
    }
}

int match(char a, char b) {
    if (a == '{' && b == '}' || a == '(' && b == ')' || a == '[' && b == ']')
    {
        return 1;
    }
    else
    {
        return 0;
    }
}

int parMatch(char *exp) {
    struct stack *s = malloc(sizeof(struct stack));
    s->arr = (char *)malloc(s->size * sizeof(char));
    s->size = 100;
    s->top = -1;
    char char_pop;
    for (int i = 0; exp[i] = '\0'; i++)
    {
        if (exp[i] == '(' || exp[i] == '{' || exp[i] == '[')
        {
            push(s, exp[i]);
        }
        else if (exp[i] == ')' || exp[i] == '}' || exp[i] == ']')
        {
            return 0;
        }
        char_pop = pop(s);
        if (!match(char_pop, exp[i]))
        {
            return 0;
        }
    }
    if (isEmpty(s))
    {
        return 1;
    }
    else
    {
        return 0;
    }
}

int main() {
    char *exp = "[]{}()";
    if (parMatch(exp))
    {
        printf("Match Successfull....!");
    }
    else
    {
        printf("Match not Successfull....!");
    }
    return 0;
}

标签: cdata-structuressegmentation-faultstack

解决方案


您的代码导致错误的原因是由于您的循环exp[i] = '\0';条件中的语句。for这在逻辑上是不正确的(解释如下),您不能修改使用char*.

你为什么这么问?阅读为什么在写入使用字符串文字初始化的“char *s”而不是“char s[]”时会出现分段错误?


您的代码中还有其他几个错误:

  1. 这不是您在 c, 中分配字符串的方式char *exp = "[]{}()";。虽然它确实有效,但它会产生警告,不推荐使用。阅读将字符串分配给字符数组

  2. 您尚未初始化s->size,但您malloc()在此行中使用它s->arr = (char *)malloc(s->size * sizeof(char));

  3. 您将push()函数的返回类型声明为int但在条件之后没有返回任何内容else。这是未来的潜在错误。它也会导致警告。

  4. 您的pop()函数的实现存在逻辑和语法缺陷。pop()函数的返回类型是但int你返回char类型。此外,您首先递减ptr->top然后返回新ptr->top位置的字符,即最终返回低于当前顶部的字符。

  5. 这不是exp[i] = '\0'您检查 for 循环的终止条件以char*在 c 中结束字符串的方式。你应该改写exp[i] != '\0'.

  6. return 0;一遇到)or}]。相反,您应该检查是否可以从堆栈中弹出相应的左大括号,如果可以,则检查更多字符else return 0;

以下是修复了上述所有错误的代码。

#include <stdio.h>
#include <stdlib.h>
struct stack {
    int size;
    int top;
    char *arr;
};

int isEmpty(struct stack *ptr) {
    if (ptr->top == -1)
    {
        return 1;
    }
    return 0;
}

int isFull(struct stack *ptr) {
    if (ptr->top == ptr->size - 1)
    {
        return 1;
    }
    return 0;
}

int push(struct stack *ptr, char val) {
    if (isFull(ptr))
    {
        return 1;
    }
    else
    {
        ptr->top++;
        ptr->arr[ptr->top] = val;
    }
    return 0;
}

char pop(struct stack *ptr) {
    char val;
    if (isEmpty(ptr))
    {
        return '\0';
    }
    else
    {
        val = ptr->arr[ptr->top];
        ptr->top--;
        return val;
    }
}

int match(char a, char b) {
    if ((a == '{' && b == '}') || (a == '(' && b == ')') || (a == '[' && b == ']'))
    {
        return 1;
    }
    else
    {
        return 0;
    }
}

int parMatch(char exp[]) {
    struct stack *s = malloc(sizeof(struct stack));
    s->size = 100;
    s->arr = (char *)malloc(s->size * sizeof(char));

    s->top = -1;
    char char_pop;
    for (int i = 0; exp[i] != '\0'; i++)
    {
        if (exp[i] == '(' || exp[i] == '{' || exp[i] == '[')
        {
            push(s, exp[i]);
        }
        else if (exp[i] == ')' || exp[i] == '}' || exp[i] == ']')
        {   // You have one closing brace but your stack is empty, then return 0
            if (isEmpty(s))
            {
                return 0;
            }
            else
            {   // If you reach here then it ensures that stack is not empty.
                char_pop = pop(s);
                if (!match(char_pop, exp[i]))
                {
                    return 0;
                }
            }
        }
    }
    if (isEmpty(s))
    {
        return 1;
    }
    else
    {
        return 0;
    }
}

int main() {
    char exp[100] = "{}}[](";
    if (parMatch(exp))
    {
        printf("Match Successfull....!");
    }
    else
    {
        printf("Match not Successfull....!");
    }
    return 0;
}

推荐阅读