在c - program crushes中将lisp字符串转换为树,但在调试模式下运行

时间:2015-12-10 21:35:47

标签: c debugging memory

我在C编写程序,假设将表示树的字符串解析为C中的实际树。

字符串格式为Lisp样式: 例如以下字符串"(A(B)(C)(D))"将创建一个树,其中A为根,B C D为3个孩子,

这是我的树代码:

#include <stdlib.h>
#include <stdio.h>
#include "SP_Tree.h"

typedef struct SP_NODE {
    char* value;
    int numchilds;
    struct SP_NODE* parent;
    struct SP_NODE** childs;
} SP_NODE;

SP_NODE* SPTreeCreate(char* value){
    SP_NODE *tree = (SP_NODE*)malloc(sizeof(SP_NODE));
    SP_NODE **childs = (SP_NODE**)malloc(sizeof(SP_NODE)*10);

    // initialize node data
    tree->childs = childs;
    tree->value = value;
    tree->parent = NULL;
    tree->numchilds = 0;
    return tree;
}
SP_NODE* SPInsertChild(SP_NODE* parent, SP_NODE* child, int index){
    // add node to parent in index place
    if (parent != NULL){
        parent->childs[index] = child;
        parent->numchilds++;
        child->parent = parent;
    }
    return child;
}
void SPDestroyTree(SP_NODE* root){
    if (root) {
        for (int i = 0; i < root->numchilds; i++){
            if (root->childs[i]!= NULL){
                SPDestroyTree(root->childs[i]);
            }
        }
        free(root->value);
        free(root);
    }
}

这是我的解析器代码:

SP_NODE* SPCreateLispTree(char* lisp){
    // create tree from first node
    int root_index = SPFindRoot(lisp);
    char* root_str = (char*)malloc(sizeof(char)*(root_index));
    strncpy(root_str, lisp+1, root_index -1);
    root_str[root_index-1] = '\0';
    SP_NODE* root = SPTreeCreate(root_str);

    // stop condition - current root ending with )
    if (lisp[root_index] == ')' ){
        return root;
    }

    // loop over all subtrees, add child to tree from each subtree
    int i = 0;
    int start_index = root_index;
    int next_index = SPFindNextSubtree(lisp,start_index);
    while (next_index > 0){
        // create tree from next subtree in lisp
        char* new_lisp = (char*)malloc(next_index-start_index+1);
        strncpy(new_lisp, lisp+start_index, next_index-2);
        new_lisp[next_index-start_index] = '\0';

        SP_NODE* next_child = SPCreateLispTree(new_lisp);

        // insert this new child to root
        SPInsertChild(root,next_child,i);

        // look for next subtree
        start_index = next_index;
        next_index = SPFindNextSubtree(lisp,start_index);
        i++;
    }
    return root;
}
int SPFindNextSubtree(char* lisp,int start_index){
    // run over string until we get #left_Parentheses == #right_Parentheses
    int i = start_index + 1;
    int left = 1;
    int right = 0;
    while (lisp[i] != '\0' && left != right){
        if (lisp[i] == '('){
            left++;

        }else if (lisp[i] == ')'){
            right++;
        }
        i++;
    }
    // if we finished with uneven number of Parentheses, its the last subtree
    if (left != right){
        fflush(stdout);
        return -1;
    }
    return i;
}
int SPFindRoot(char* lisp){
    // root will be from ( until first between ( or )
    // get index of first )
    char* right = strchr(lisp,')');
    int right_index = right - lisp;

    // get index of second '(' (first char will always be '(')
    char* left = strchr(lisp+1,'(');
    int left_index = left - lisp;

    // chose smaller index
    int index = right_index;
    if (left != NULL && left_index < right_index){
        index = left_index;
    }
    return index;
}

代码以递归方式在字符串上运行,找到当前根并从该根创建一个节点,然后在该根之后找到每个子树并从中创建一个子树。

我的问题是 - 该程序适用于小输入 - 但是对于更大的输入,例如:

char* lisp = "(+(2)(*(5)(3(2)(3))(4(!)(2))(1))(2(3)(4)))";
SP_NODE* tree = SPCreateLispTree(lisp);

我的节目粉碎了。

但是 - 当我在调试模式下运行时它不会被压碎 - 它会产生所需的输出。

不确定我做错了什么以及如何调试它。

1 个答案:

答案 0 :(得分:0)

<?php $Csv_array=array(); $Folder_array = array(); $line_number = false; array_push($Csv_array,'234234','45454','78797'); array_push($Folder_array,'723325_Test_letter.pdf','753434_Test_letter.pdf','75443434_Test_letter.pdf'); ?> 未初始化为childs[index]。                      - BLUEPIXY

NULL - &gt;
strncpy(new_lisp, lisp+start_index, next_index-2);                      - BLUEPIXY