指针(树)如何在2个不同的行中返回2个不同的值?

时间:2014-03-06 14:56:49

标签: c

我的程序中有以下代码:

/*Making a tree using linked lists.
*/
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
typedef struct node
{
    int value;
    struct node * left;
    struct node * right;
}Node;
Node * tree;
Node * maketree(int number)
{
    Node p = { number, NULL, NULL };
    return &p;
}
int main()
{
    int a[5] = { 1, 2, 3, 1, 4 };
    int number;
    number = a[0];
    tree = maketree(number);
    printf("Root has a value of %d\n", tree->value);
    printf("Root has a value of %d\n", tree->value);
}

输出:

Root的值为1

Root的值为“Some garbage value!”

我无法理解树在某些其他地址(或以某种方式打印某些垃圾值)的方式,当我完全没有使用它并在2个连续的行中打印它的值时!

2 个答案:

答案 0 :(得分:4)

您正在返回&p,即本地变量的地址。

maketree()退出时,此变量超出范围,使取消引用指针成为未定义的行为。

实际上,您正在取消引用指向maketree() 分配的堆栈空间的指针,但已取消分配且很可能重新使用(printf() ,这是一个相当重的功能)。这完全是无效的代码。

修复是在堆上分配新节点:

Node * maketree(int number)
{
  Node *p = malloc(sizeof *p);
  if(p != NULL)
  {
    p->value = number;
    p->left = p->right = NULL;
  }
  return p;
}

答案 1 :(得分:1)

在功能

Node * maketree(int number)
{
    Node p = { number, NULL, NULL };
    return &p;
}

您正在返回本地变量p的地址。本地意味着变量p的内存位置在函数结束后不再为p保留。没有什么能阻止它被覆盖。这称为未定义的行为。

您应该使用动态分配:

 Node * maketree(int number)
 {
    Node *pp;
    pp = malloc(sizeof(*pp));
    if(pp != NULL)
    {
        pp->value = number;
        pp->left = NULL;
        pp->right = NULL;
    }
    return pp;
 }