Printf 与 scanf 要求输入。 BST 循环错误

Posted

技术标签:

【中文标题】Printf 与 scanf 要求输入。 BST 循环错误【英文标题】:Printf with scanf asking for input. Loop error with BST 【发布时间】:2014-12-11 09:47:25 【问题描述】:

我一直试图看看为什么 printf 在打印文件的输入后没有中断循环。 .c 文件是 BST,我现在正在测试是否已构建树但似乎无法退出 printf 循环。我需要 printf 循环才能正确输出代码。关于为什么会发生此错误的任何建议。显示了完整的代码和输出。

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


///Author: Joe W

//arbitrary list of temp nodes

TreeNode *new_node, *root, *tmp, *parent;
int elemArray[100], i1, i2, i0;

/*
Insert a new node into the tree by referencing the root and using recursion
*/

    TreeNode* getN(int dataElem) 
        TreeNode* temp;
        temp = malloc(sizeof(TreeNode*));
        temp-> left = NULL;
        temp-> right = NULL;
        temp->data =  dataElem;
        return temp;
     



TreeNode* addNodeToTree(TreeNode *root, int data) 
    TreeNode* newNode = malloc(sizeof(TreeNode*));
    if (root == NULL)
    

                                            // thingy too. Creating a function too,
                                            // for you to look at.
        root = newNode;
        return root;
    
    else
    
        TreeNode* parent = malloc(sizeof(TreeNode*));
        TreeNode* current = malloc(sizeof(TreeNode*));
        parent = current = root;
        // This loop will actually help us, find the `parent`, 
        // of the `newNode`(which is to be inserted)
        while (current != NULL)
        
            parent = current;
            if (current->data > data)
                current = current->left;
            else if (current->data < data)
                current = current->right;
        
        // Now once, we have found, the node, under which the
        // newNode will be placed, now we have to check, whether
        // newNode will become a `left child/right child` of the 
        // parent.
        newNode = getN(data);
        if (parent->data > data)
            parent->left = newNode;
        else if (parent->data < data)
            parent->right = newNode;


        return root;
    



void build_Tree(TreeNode** root, const int elements[], const int count) 

    //TreeNode* node = malloc(sizeof(TreeNode*));
    //node->left = node ->right = NULL;



    for ( i0 = 0; i0 < count; ++i0 )
        *root = addNodeToTree(*root, elements[count]);
    


这编译得很好。该错误在文件接受用户输入并开始显示代码后开始。使用 printf 语句。

int main( int argc, char *argv[] ) 

    //Throw error is *Argv[] is not an integer
    //assuming it was an integer
    int cnt = atoi( argv[1] );
    printf( "number is %d\n", cnt );
    //
    printf("Enter %i integer values to place in tree:\n", cnt);
    for ( i1 = 0; i1 < cnt; ++i1) 
        scanf( "%d", &elemArray[i1] );
    

    //first ouput "INput Values"

    printf( " Input Values:\n " );  
     for ( i2 = 0; i2 < cnt; ++i2) 
               printf( "%d\n", elemArray[i2] );
               printf("building tree0\n");
        
    printf("building tree");
    TreeNode** root = malloc(sizeof(TreeNode*));
    printf("building tree");
    build_Tree(root, elemArray, cnt );
    printf("Tree Built");
    printf( "Preorder:\n ");

    //traverse
    //TreeNode* tempN = malloc(sizeof(TreeNode*));
    //tempN->data= 5;

    traverse( *root, PREORDER);             //pass the pointer of root to traverse the tree

    //traverse a single node 
    printf( "Inorder:\n ");

    printf( "Postorder:\n ");


    //Build tree with each element

    return 0;


void traverse( const TreeNode* root, const TraversalType type ) 

    if ( type == PREORDER) 
             if (root != NULL)
             
                printf("%d", root->data);
                traverse( root->left, PREORDER);
                traverse( root-> right, PREORDER);
            
    





    /**
    void insertNode(TreeNode** root, TreeNode* new_node) 

       if (new_node-> data < *root-> data) 
          if (*root-> left == NULL) 
             *root-> left == new_node;
          else
            insert(*root->left, new_node);
       

      if (new_node->data > *root->data) 
        if(*root-> right ==NULL)
          *root->right = new_node;
        else
          insert(*root->right, new_node);
      
    
    **/


//question1: what is the 

这是我开始运行代码的地方

jw8453@idaho:~/Courses/CS243/Homework/5$ make
gcc -ggdb  -c bst.c
gcc -ggdb -o bst bst.o  -lm
jw8453@idaho:~/Courses/CS243/Homework/5$ ./bst 5
number is 5
Enter 5 integer values to place in tree:
1
2
3
4
5
 Input Values:
 1
building tree0
2
building tree0
3
building tree0
4
building tree0
5
building tree0



this isnt supposed to be in the printf loop

注意:问题是BST build tree double pointers的延续

【问题讨论】:

没有必要做TreeNode* parent = malloc(sizeof(*parent));,因为这里的*parent基本上是一个pointer,假设指向某个节点。由于 root 指向某个地方,您只需执行parent = root,现在parent 将获得root 指向的位置地址。 我是否也不需要TreeNode* current = malloc(sizeof(TreeNode)); 并定义parent = current = root TreeNode* newNode = malloc(sizeof(TreeNode*));实际上是指,分配一个空间(这里是指针,可以保存TreeNode的地址),并将地址给newNode。这里sizeof(TreeNode *) 将始终是4 字节/操作系统的字长。实际上需要的是内存中用于保存TreeNode 并将此地址返回给newNode 的空间,这里sizeof(*newNode) 将是4 + 4 + 4 字节,对于intpointer(left)pointer(right) 在进一步移动之前,只需尝试打印两者的值,例如 printf("Size TreeNode *: %d\n", sizeof(TreeNode *));printf("Size *newNode: %d\n", sizeof(*newNode));。你会得到一个公平的想法,这两个东西都指的是什么。第一个是指针的大小,尽管后者是TreeNode 的整体大小。 @nIcE cOw 我不知道这是否与问题相关,但树似乎没有正确构建,尽管所有打印状态都执行,traverse() 不与打印一起运行。现在,你说的是对的,但是*newNodeTreeNode* 的结构是一样的,因为typedef struct TREENODE int data; struct TREENODE *left; struct TREENODE *right; TreeNode; 【参考方案1】:

这是错误的:

TreeNode* newNode = malloc(sizeof(TreeNode*));

改为

TreeNode* newNode = malloc(sizeof(TreeNode));

TreeNode* newNode = malloc(sizeof(*newNode));

这里:

    TreeNode* parent = malloc(sizeof(TreeNode*));
    TreeNode* current = malloc(sizeof(TreeNode*));
    parent = current = root;

您有内存泄漏,为parentcurrent 保留空间,然后将这些变量分配给另一个地址,同样用于:

TreeNode* newNode = malloc(sizeof(TreeNode*));
...
newNode = getN(data);

我建议

void setN(TreeNode *node, int dataElem) 
    node->left = NULL;
    node->right = NULL;
    node->data = dataElem;

...
setN(newNode, data);

而不是

TreeNode* getN(int dataElem) 
    TreeNode* temp;
    temp = malloc(sizeof(TreeNode*));
    temp-> left = NULL;
    temp-> right = NULL;
    temp->data = dataElem;
    return temp;

...
newNode = getN(data);

【讨论】:

好的,一旦我将 addNodeToTree 更改为在 root = newNode 之前有 newNode 并再次在 else 语句中。然后我改变了 main 的 malloc(sizeof(TreeNode))。我不知道如何避免 parent = current = root 的内存泄漏。 我将 parent = current = root 更改为 *parent = *current = *root 并修复了它 最后一个问题,如果允许,我可能会移动到另一个页面,但是当我构建树时,如何分配指针和节点空间来创建第一个节点(节点)到 addNodeToTree?现在,我在 build_Tree 中创建了一个节点,然后将这些值设置为 null。在我将 *root 设置为节点后,我使用带有 *root 的 addNoteToTree 的 for 循环。

以上是关于Printf 与 scanf 要求输入。 BST 循环错误的主要内容,如果未能解决你的问题,请参考以下文章

C语言中的printf()与scanf()

scanf函数与printf函数用法

C语言,如何给3个char变量赋值?不能直接char a='D',这种。要求用printf,scanf.

scanf 与 gets ,printf 与puts 函数比较

getchar和putchar与scanf和printf的区别

输出与输出:putchar() getchar() printf() scanf() puts() gets() sscanf()