我的程序中有以下代码:
/*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个连续的行中打印它的值时!
答案 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;
}