这段二进制代码会导致任何问题吗?

时间:2012-03-04 09:00:32

标签: c++

我写了一段代码,它在我的系统上运行良好。我没有任何问题,但我有一些问题,我将在下面列出。我想知道是否存在真正的问题。

# include <iostream>
# include <stdio.h>
# include<conio.h>
using namespace std;

struct tree
{
  int data;
  struct tree * left;
  struct tree * right;
};

struct tree * insert(struct tree * root,int value)
{
     if(root==NULL)
     {
      struct tree *node=(struct tree *)malloc(sizeof(struct tree));
      node->data = value;
      node->left=NULL;
      node->right=NULL;
      return node;
     }
     else if(root->data > value)
       root->left=insert(root->left,value);
     else {
       root->right=insert(root->right,value);
       /*return root;*/  // code works fine for me without this return
     }
}

void display(struct tree * root)
{ 
    if (root!=NULL)
    {
      display(root->left);
      cout << "value is : " << root->data << " \n";
      display(root->right);
    }
}

int main()
{
   struct tree* root=NULL;
   root=insert(root,8);
   insert(root,6);
   insert(root,5);
   insert(root,2);
   insert(root,1);
   insert(root,7);
   insert(root,15);
   display(root);
   delete root;
   getch();
}

我的代码在插入函数中没有return root语句时工作正常。令我担心的是,在创建根和在此递归函数中插入最终元素之间的递归调用期间,我没有返回任何内容。但事情对我来说仍然很好。

在更复杂的编码场景中,这会成为未来的问题吗?

5 个答案:

答案 0 :(得分:1)

如果你不确定,那就测试一下:-)。 TDD,BDD是一种非常好的编码方式(唯一的好方法吗?)。在c ++中有很多工具可以做到这一点。我最近使用谷歌测试,这很好,很容易。

http://code.google.com/p/googletest/

每个测试对应于您通过编写代码来满足的要求。这称为行为驱动开发。了解这一点,你将大大提高你的技能。

对于内存泄漏,请使用valgrind(http://valgrind.org/)之类的工具,它会为您检查。

答案 1 :(得分:1)

是的,这可能是个问题。它现在不是问题,因为你从不使用返回值,除非在第一次调用中(当函数返回新创建的根节点时)。

在稍后调用insert后,返回值为 undefined 。如果调用者使用从insert获取的 undefined 指针,您将看到奇怪且难以调试的问题或分段错误。

定义函数预期返回的内容(例如,“创建的最后一个节点”或“最后一次插入的节点”或类似内容),然后确保返回该函数。如果你认为在某些情况下函数无法合理返回,至少让它返回0(或nullptr)。

评论中记录函数可以返回的内容也是一个好主意,即使您是唯一一个将使用该函数的人。在某些时候,你会忘记函数究竟是做什么的,然后评论会很有用。

答案 2 :(得分:1)

此代码工作正常,因为insert在创建新节点时返回某些内容,并将指向新节点的指针返回到其父节点。没有必要将父指针返回给祖父 - 祖父已经拥有父指针。因此插入正确完成。

还有一点需要注意:您的代码容易出现内存泄漏。 delete root;中的语句main不足以释放所有已分配的内存。要删除所有malloc - 内存,您需要一个与insert非常相似的递归函数:当您向node *传递left时,该函数将释放right先和{{1}}孩子,然后自由自在。这就像二叉树的后序遍历。

答案 3 :(得分:1)

delete来自malloc的{​​{1}}数据。始终使用free代替。 UB将以其他方式结果。

答案 4 :(得分:0)

我不确定您的代码是否可以在没有任何警告的情况下成功编译,因为您声明insert函数返回指针,但并非所有控制路径都返回一个值(至少在我的机器上使用Visual Studio 2008安装)。代码也可能导致内存泄漏,因为您只删除了根节点,而其所有子节点仍处于活动状态。有很多关于如何用C ++编写二叉搜索树的文章。希望它有所帮助!