Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C-释放结构时接收SIGABRT-系统特定?_C_Linux_Eclipse_Struct_Free - Fatal编程技术网

C-释放结构时接收SIGABRT-系统特定?

C-释放结构时接收SIGABRT-系统特定?,c,linux,eclipse,struct,free,C,Linux,Eclipse,Struct,Free,我目前正在修补C语言中的二叉树,但我遇到了一个我自己似乎无法解决的问题。我正在使用EclipseMars作为我的IDE 该项目的基本思想是由树节点组成二叉树。这些节点是结构,并且在(struct Books)中包含一个结构,因此treeNode和Books有两个独立的lib 这些是有问题的结构: void bst_clear(struct TreeNode *tree_node) { //Clears all nodes recursively if (tree_node->

我目前正在修补C语言中的二叉树,但我遇到了一个我自己似乎无法解决的问题。我正在使用EclipseMars作为我的IDE

该项目的基本思想是由树节点组成二叉树。这些节点是结构,并且在(struct Books)中包含一个结构,因此treeNode和Books有两个独立的lib

这些是有问题的结构:

void bst_clear(struct TreeNode *tree_node) {
    //Clears all nodes recursively
    if (tree_node->left != NULL) {
        bst_clear(tree_node->left);
    }
    if (tree_node->right != NULL) {
            bst_clear(tree_node->right);
    }

    tree_node->key = NULL;
    tree_node->book = NULL;

    free((void*) tree_node);
    return;
}
TreeNode:

struct TreeNode {
    struct Book *book;
    unsigned long key;
    struct TreeNode *left;
    struct TreeNode *right;
};
书籍:

现在,节点可以很好地创建,插入/打印功能也可以很好地工作。但是,我还有一个clear()函数,它应该释放以前分配的所有内存。Malloc仅在新的_xxx()函数中调用:

struct TreeNode *new_tree_node(unsigned long ISBN, char *author, char *title) {
    //Creating and allocating the new TreeNode
    struct TreeNode *new_tree_node;
    new_tree_node = (struct TreeNode*) malloc(sizeof(struct TreeNode));

    //Creating the book
    struct Book *new_Book = newBook(ISBN, author, title); 

    new_tree_node->book = new_Book;

    new_tree_node->left = NULL;
    new_tree_node->right = NULL;

    new_tree_node->key = ISBN;

    return new_tree_node;
}
和newBook()

现在,当我尝试运行clear()函数时,当我尝试释放一个树节点并且进程停止时,我会收到一个“SIGABRT:Aborted”信号。Eclipse还返回:

“在0x75ffff7a4bcc9上没有“raise()可用的源代码”。

起初我认为这是因为我的系统找不到标准功能之一,但控制台也会打印:

***在/home/max/workspace/bst_2/Debug/bst_2中出错:双重释放或损坏(输出):0x00007fffffe030***

这让我相信代码中确实存在一个问题

这就是所讨论的功能:

void bst_clear(struct TreeNode *tree_node) {
    //Clears all nodes recursively
    if (tree_node->left != NULL) {
        bst_clear(tree_node->left);
    }
    if (tree_node->right != NULL) {
            bst_clear(tree_node->right);
    }

    tree_node->key = NULL;
    tree_node->book = NULL;

    free((void*) tree_node);
    return;
}
有趣的是,这只会发生在使用Linux操作系统(Mint 17.1)时——无论是在虚拟机中还是作为双引导系统。我的主操作系统是Windows 7 64位,编译和运行时没有任何问题,并且完全完成了整个过程

我不确定代码是否真的出了问题(可能是这样的,我还是个新手),或者我的操作系统是否真的弄糟了。但由于这在虚拟机和实际系统中都发生了,所以可能与缺少系统库无关(我猜)

有人知道这里发生了什么吗

编辑:valgrind输出:

==2946== Invalid free() / delete / delete[] / realloc()
==2946==    at 0x4C2BDEC: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==2946==    by 0x4008D3: bst_clear (booktree.c:84)
==2946==    by 0x400884: bst_clear (booktree.c:73)
==2946==    by 0x400884: bst_clear (booktree.c:73)
==2946==    by 0x400D17: main (main.c:66)
==2946==  Address 0xfff000030 is on thread 1's stack
==2946== 
==2946== Invalid free() / delete / delete[] / realloc()
==2946==    at 0x4C2BDEC: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)

...

==2946== 
==2946== 
==2946== HEAP SUMMARY:
==2946==     in use at exit: 128 bytes in 4 blocks
==2946==   total heap usage: 10 allocs, 10 frees, 280 bytes allocated
==2946== 
==2946== LEAK SUMMARY:
==2946==    definitely lost: 128 bytes in 4 blocks
==2946==    indirectly lost: 0 bytes in 0 blocks
==2946==      possibly lost: 0 bytes in 0 blocks
==2946==    still reachable: 0 bytes in 0 blocks
==2946==         suppressed: 0 bytes in 0 blocks
==2946== Rerun with --leak-check=full to see details of leaked memory
该错误出现了多次-所讨论的行是free()命令-第73行只是递归函数调用

现在,如果我做对了,我正在尝试释放堆栈只读内存中的一个对象,对吗?我唯一能想到的是结构声明,它可能包含静态元素

我还想指出的是,在Windows机器上运行此程序时没有任何问题-有人知道原因吗

编辑2:

以下是创建节点的方式:

char* root_author;
char* root_title;
root_author = "A B C\0";
root_title = "ABC\0";
struct TreeNode *root;
root = new_tree_node(579610, root_author, root_title);

char* n1a;
char* n1t;
n1a = "B C D";
n1t = "BCD";
struct TreeNode *n1 = new_tree_node(406759, n1a, n1t);
bst_insert(root, n1);
这是insert()函数:

   void bst_insert(struct TreeNode *tree_node, struct TreeNode *new_node) {
    if (new_node->key < tree_node->key) {
        //If the key is smaller -> insert left
        if (tree_node->left == NULL) {
            //There is no left node yet
            tree_node->left = new_node;
            return;
        } else
            bst_insert(tree_node->left, new_node); //There is a node -> pass it on
    }

    else {
        //The key is larger -> right
        if (tree_node->right == NULL) {
            //There is no left node yet
            `enter code here`tree_node->right = new_node;
                return;
            } else
                bst_insert(tree_node->right, new_node); //There is a node -> pass it on
        }
    }
void bst\u insert(结构树节点*树节点,结构树节点*新节点){
如果(新建节点->键<树节点->键){
//如果键较小->向左插入
if(树节点->左==NULL){
//还没有左节点
树\节点->左=新\节点;
返回;
}否则
bst_insert(tree_node->left,new_node);//有一个节点->传递它
}
否则{
//钥匙更大->右
if(树节点->右==NULL){
//还没有左节点
`在此处输入代码`tree\u node->right=new\u node;
返回;
}否则
bst_insert(tree_node->right,new_node);//有一个节点->传递它
}
}

请输入
malloc()的返回值
C
中的族。首先构建一个包含符号的调试版本的代码。然后学习使用工具,例如可以帮助您发现内存访问问题的工具。此外,在构建一个导致此行为的小树后,请尝试确保树中没有任何意外循环,或者没有一些子节点未插入g到树中已经存在的另一个节点。在
valgrind
中运行您的程序。它将明确告诉您哪行代码是错误的。而
double free
,通常意味着您在同一个指针上多次调用
free
。这样,您正在泄漏
键和
书的内存。它们为什么会这样首先是指针?除此之外,所显示的代码片段看起来不错,因此正如前面所指出的,使用类似于
valgrind
Please的
malloc()的返回值
C
中的族。首先构建一个包含符号的调试版本的代码。然后学习使用工具,例如可以帮助您发现内存访问问题的工具。此外,在构建一个导致此行为的小树后,请尝试确保树中没有任何意外循环,或者没有一些子节点未插入g到树中已经存在的另一个节点。在
valgrind
中运行您的程序。它将明确告诉您哪行代码是错误的。而
double free
,通常意味着您在同一个指针上多次调用
free
。这样,您正在泄漏
键和
书的内存。它们为什么会这样首先是指针?除此之外,显示的代码片段看起来不错,正如前面所指出的,使用类似
valgrind
   void bst_insert(struct TreeNode *tree_node, struct TreeNode *new_node) {
    if (new_node->key < tree_node->key) {
        //If the key is smaller -> insert left
        if (tree_node->left == NULL) {
            //There is no left node yet
            tree_node->left = new_node;
            return;
        } else
            bst_insert(tree_node->left, new_node); //There is a node -> pass it on
    }

    else {
        //The key is larger -> right
        if (tree_node->right == NULL) {
            //There is no left node yet
            `enter code here`tree_node->right = new_node;
                return;
            } else
                bst_insert(tree_node->right, new_node); //There is a node -> pass it on
        }
    }