堆栈和二进制表达式树出现双重释放或损坏错误

语言尼龙

尝试从堆栈构建二进制表达式树时,出现以下错误。我认为问题在于我正在递归函数中弹出,我认为我正在空栈中弹出但我不知道解决方案。

*检测到glibc ./interp:双重释放或损坏(fasttop):0x0934d018 * *

这是我的代码:

//This is the main
int main(int argc, char *argv[]){
   TreeNode *node;
   StackNode *stack = NULL;
   push(&stack, "a");
   push(&stack, "b");
   push(&stack, "+");
   //while (emptyStack(stack)!= 1){ //this while loop works correctly, which verifies that my stack implementation is working.
   //  printf("Top is : %s\n", top(stack));
   //  pop(&stack);
   //}
   node = buildTree(stack);


//buildTree function
TreeNode *buildTree(StackNode *stack){
   int integer; //to check for an integer
   char *data = top(stack);
   char *pch = strchr(top(stack), '.'); //to check for a double, looks for the decimal point
   if (emptyStack(stack) != 0){
       //stack is empty
       fprintf(stderr, "Invalid expression, not enough tokens");
       return NULL;
   }
   else if (sscanf(top(stack), "%d", &integer) != 0){
       printf("parser: integer node\n");
       //got an integer
       pop(&stack);
       return makeTreeNode(data, NULL, NULL);
   }
   else if (pch != NULL){
       printf("parser: double node\n");
       //got a double
       pop(&stack);
       return makeTreeNode(data, NULL, NULL);
   }
   else if ( isalpha((int)data[0])){
       //got a variable
       printf("parser: variable node\n");
       pop(&stack);
       return makeTreeNode(data, NULL, NULL);
   }
   else{
       //got an operator, recurse
       printf("parser: operator node\n");
       pop(&stack);
       return makeTreeNode(data,buildTree(stack), buildTree(stack));
   }
}

//makeTreeNode
TreeNode* makeTreeNode(char token[], TreeNode* left, TreeNode* right){
    //this function works correctly

这是我的堆栈函数

StackNode* makeStackNode(char* data, StackNode* next){
   StackNode *node;
   node = malloc(sizeof(StackNode));
   node->data = data;
   node->next = next;
   printf("Making stack node of : %s\n", data);
   return node;
}


char* top(StackNode* stack){
   if (emptyStack(stack)!= 0){
      exit(EXIT_FAILURE);
   }
   else{
      return stack->data;
   }
}

void push(StackNode** stack, char* data){
   StackNode* ptr;
   ptr = makeStackNode(data, *stack);
   *stack = ptr;
   printf("Pushed stack node \n");
}

//pop from stack
void pop (StackNode** stack){
   if (emptyStack(*stack)!=0){
      exit(EXIT_FAILURE);
   }
   else{
      printf("Popping node \n");
      StackNode* ptr = *stack;
      printf("Right before the pop, stack = %s\n", top(*stack));
      *stack = ptr->next;
      printf("Right before the free, stack = %s\n", top(*stack));
      free(ptr);
   } 
}

//returns 1 if stack is empty, 0 if it is not empty
int emptyStack(StackNode* stack){
   if (stack == NULL){
      return 1;
   }
   else{
      return 0;
   }
}

打印输出:

Making stack node of : a
Pushed stack node
Making stack node of : b
Pushed stack node
Making stack node of : +
Pushed stack node
parser: operator node
Popping node
Right before the pop, stack = +
Right before the free, stack = b
parser: variable node
Popping node
Right before the pop, stack = b
Right before the free, stack = a
parser: integer node //this should be a variable node
Popping node
Right before the pop, stack = //this should be stack = a
Right before the free, stack = a  //this should be blank
WhozCraig

您的问题是这样的:

return makeTreeNode(data, buildTree(stack), buildTree(stack));

stack您认为传递给每个这些函数调用有什么价值

答:相同的值。当一个(我们不知道,不关心哪个,因为那是一个序列点问题)时,另一个调用在相同(现已释放)的节点上使用相同的堆栈指针,并在认为生命很好时快乐地运行,当实际上,它正要沿着未定义行为的道路前进。

buildTree()就像在堆栈管理功能中的其他位置一样,您的堆栈需要按地址传递给,(因为这正是buildTree()在做的事情:管理输入堆栈)。

最终,一旦您解决了该问题,就需要解决该函数调用的顺序点问题,但是我要留给您。(不是真的,请参阅下文)

//buildTree function
TreeNode *buildTree(StackNode **stack)
{
    char *data=NULL;
    int integer;

    if (stack == NULL)
    {
        //stack is empty
        fprintf(stderr, "Invalid expression, not enough tokens");
        return NULL;
    }

    // reference top of stack data
    data = top(*stack);

    if (strchr(data,'.') != NULL)
    {
        printf("parser: double node\n");
        pop(stack);
        return makeTreeNode(data, NULL, NULL);
    }

    if (sscanf(data, "%d", &integer) != 0)
    {
        printf("parser: integer node\n");
        pop(stack);
        return makeTreeNode(data, NULL, NULL);
    }

    if ( isalpha((int)data[0]))
    {
        printf("parser: variable node\n");
        pop(stack);
        return makeTreeNode(data, NULL, NULL);
    }

    //got an operator, recurse
    printf("parser: operator node\n");
    pop(stack);

    TreeNode *rhs = buildTree(stack);
    TreeNode *lhs = buildTree(stack);
    return makeTreeNode(data, lhs, rhs);
}

//This is the main
int main(int argc, char *argv[])
{
    TreeNode *node;
    StackNode *stack = NULL;
    push(&stack, "a");
    push(&stack, "b");
    push(&stack, "+");
    node = buildTree(&stack);
}

输出量

parser: operator node
parser: variable node
parser: variable node

旁注:我对进行了一些清理buildTree(),包括反转您首先检查的内容:十进制或整数。123.456贯穿sscanf(data, "%d", &integer)将很高兴地吸123走,这不是您想要的外观。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

堆栈和二进制表达式树出现双重释放或损坏错误

来自分类Dev

二进制表达式树的缀

来自分类Dev

错误:对二进制表达式无效的操作数(“ float”和“ float”)

来自分类Dev

使用链接比较运算符评估二进制表达式树

来自分类Dev

计算二进制表达式树的值

来自分类Dev

如何从前缀符号构建二进制表达式树?

来自分类Dev

快速的二进制表达式问题

来自分类Dev

如何修复“对二进制表达式无效的操作数”错误?

来自分类Dev

“对二进制表达式无效的操作数”错误

来自分类Dev

无效的操作数到二进制表达式错误消息

来自分类Dev

二进制表达式的无效操作数错误

来自分类Dev

二进制表达式的无效操作数(“ RadioDevice”和“ const RadioDevice”)

来自分类Dev

无效的二进制表达式操作数(Int和NSNumber *)

来自分类Dev

对二进制表达式无效的操作数(NSNumber * __strong和NSNumber *)

来自分类Dev

对二进制表达式无效的操作数(“ NSMutableArray”和“ double”)

来自分类Dev

来自字符串库组件内部的“错误:二进制表达式的无效操作数”

来自分类Dev

为什么操作数从二进制表达式接收到错误消息?

来自分类Dev

二进制表达式的无效操作数(“ ostream”(又名“ basic_ostream <char>”)和“ ostream”)

来自分类Dev

iOS NSNumber对二进制表达式无效的操作数(NSNumber *”和“ double”)

来自分类Dev

无效的操作数二进制表达式:ostream和std :: u32string

来自分类Dev

对二进制表达式无效的操作数(常量点和常量点

来自分类Dev

二进制表达式的无效操作数(“ int_node”和const“ int_node”)

来自分类Dev

对二进制表达式无效的操作数(“ ostream”(又名“ basic_ostream <char>”)和“ ostream”)

来自分类Dev

无效的操作数二进制表达式:ostream和std :: u32string

来自分类Dev

对二进制表达式无效的操作数(“ CGFloat”(又名“ double”)和“ UIView * _Nullable”)

来自分类Dev

NSInteger乘法:对二进制表达式无效的操作数

来自分类Dev

C ++-二进制表达式的无效操作数

来自分类Dev

如何从二进制表/矩阵创建表达式输入样式格式?

来自分类Dev

为二进制表达式创建AST

Related 相关文章

  1. 1

    堆栈和二进制表达式树出现双重释放或损坏错误

  2. 2

    二进制表达式树的缀

  3. 3

    错误:对二进制表达式无效的操作数(“ float”和“ float”)

  4. 4

    使用链接比较运算符评估二进制表达式树

  5. 5

    计算二进制表达式树的值

  6. 6

    如何从前缀符号构建二进制表达式树?

  7. 7

    快速的二进制表达式问题

  8. 8

    如何修复“对二进制表达式无效的操作数”错误?

  9. 9

    “对二进制表达式无效的操作数”错误

  10. 10

    无效的操作数到二进制表达式错误消息

  11. 11

    二进制表达式的无效操作数错误

  12. 12

    二进制表达式的无效操作数(“ RadioDevice”和“ const RadioDevice”)

  13. 13

    无效的二进制表达式操作数(Int和NSNumber *)

  14. 14

    对二进制表达式无效的操作数(NSNumber * __strong和NSNumber *)

  15. 15

    对二进制表达式无效的操作数(“ NSMutableArray”和“ double”)

  16. 16

    来自字符串库组件内部的“错误:二进制表达式的无效操作数”

  17. 17

    为什么操作数从二进制表达式接收到错误消息?

  18. 18

    二进制表达式的无效操作数(“ ostream”(又名“ basic_ostream <char>”)和“ ostream”)

  19. 19

    iOS NSNumber对二进制表达式无效的操作数(NSNumber *”和“ double”)

  20. 20

    无效的操作数二进制表达式:ostream和std :: u32string

  21. 21

    对二进制表达式无效的操作数(常量点和常量点

  22. 22

    二进制表达式的无效操作数(“ int_node”和const“ int_node”)

  23. 23

    对二进制表达式无效的操作数(“ ostream”(又名“ basic_ostream <char>”)和“ ostream”)

  24. 24

    无效的操作数二进制表达式:ostream和std :: u32string

  25. 25

    对二进制表达式无效的操作数(“ CGFloat”(又名“ double”)和“ UIView * _Nullable”)

  26. 26

    NSInteger乘法:对二进制表达式无效的操作数

  27. 27

    C ++-二进制表达式的无效操作数

  28. 28

    如何从二进制表/矩阵创建表达式输入样式格式?

  29. 29

    为二进制表达式创建AST

热门标签

归档