root = (TreeNode*)malloc(sizeof(TreeNode));
这句话的意思是:malloc分配一个内存空间,malloc返回的是void*,无类型指针,返回值是分配的这块空间的地址。
用(TreeNode*)强制类型转换成树节点型指针,赋值给root。因为void*不能直接赋值给别的类型的指针,所以要通过强制类型转换。root就是一个指向树节点的指针,现在他的值变成了申请这块空间的地址了。
最终建树成功的代码:
#include <stdlib.h>
#include <stdio.h>
typedef struct TreeNode{
int val;
struct TreeNode* left;
struct TreeNode* right;
} TreeNode;
void preorder (struct TreeNode* root, int* returnSize, int* ans){
if (root == NULL)
return;
ans[*returnSize] = root->val;
printf("%d\n", ans[*returnSize]);
(*returnSize) ++;
if (root->left != NULL)
{
preorder(root->left, returnSize, ans);
}
if (root->right != NULL)
{
preorder(root->right, returnSize, ans);
}
}
int* preorderTraversal(struct TreeNode* root, int* returnSize) {
int* ans = (int*)malloc(sizeof(int) * 100);
*returnSize = 0;
preorder (root, returnSize, ans);
return ans;
}
void TreeNodeCreate(TreeNode** pointer, int* size)
{
*pointer = (TreeNode*)malloc(sizeof(TreeNode));
*size ++;
(*pointer)->left = NULL;
(*pointer)->right = NULL;
}
int main()
{
int size = 0;
TreeNode* root;
TreeNode* newnode;
TreeNode* lastnode;
TreeNodeCreate(&root, &size);
root->val = 1;
TreeNodeCreate(&newnode, &size);
root->right = newnode;
newnode->val = 2;
lastnode = newnode;
TreeNodeCreate(&newnode, &size);
lastnode->left = newnode;
newnode->val = 3;
int* returnSize = (int*)malloc(sizeof(int));
int* ans;
ans = preorderTraversal(root, returnSize);
return 0;
}
bug:
“Segmentation fault”(段错误),是程序运行时常见的严重错误 “Segmentation” 源于计算机内存管理中的 “内存段(Segment)” 概念。当程序试图访问不被允许的内存段(例如未分配的内存、已释放的内存、只读内存区域等)时,操作系统会触发 “Segmentation fault”,强制终止程序以保护系统内存安全。 -----产生问题的原因是:我创建一个树节点,把主函数中定的一个指针传入函数中去新建树节点
void TreeNodeCreate(TreeNode* pointer, int size)
{
pointer = (TreeNode*)malloc(sizeof(TreeNode));
size ++;
pointer->left = NULL;
pointer->right = NULL;
}
int main()
{
int size = 0;
TreeNode* root;
TreeNodeCreate(root, size);
原代码的问题在于:值传递无法让函数内部的修改影响到外部变量。要正确创建树节点并更新 size,必须通过指针的指针传递节点指针,通过指针传递 size,才能实现 “修改外部变量” 的效果。
完整修改如下:
void TreeNodeCreate(TreeNode** pointer, int* size)//传入的值都是要改变的东西的地址
{
*pointer = (TreeNode*)malloc(sizeof(TreeNode));//二级指针 加一个*是原来的一级指针
*size ++;
(*pointer)->left = NULL;//若不加括号,默认会被理解成*(pointer->left)
(*pointer)->right = NULL;
}
int main()
{
int size = 0;
TreeNode* root;
TreeNodeCreate(&root, &size);//取地址传入函数内部去,这样函数内的改变才能传出来
接下来继续测试,要实现函数与外部参数同变化,是否都需要传递参数的地址进去:
void addone(int a)
{
a++;
return;
}
int main()
{
int a = 0;
addone(a);
printf("%d", a);
return 0;
}
运行结果a等于0,函数内的+1并没有传递到外面 改成传入地址:
#include <stdio.h>
#include <stdlib.h>
void addone(int* a)
{
(*a)++;
}
int main()
{
int a = 0;
addone(&a);
printf("%d", a);
return 0;
}
这次运行结果为1,函数内的+1成功传到外面。
因此如果想用一个函数修改主函数中的值,应该把需要修改的参数取地址传入函数,而函数的传入参数值是需要改变的变量的地址,所以这个传入参数是指向变量的指针。因此改整形数据,函数参数是一级指针;改指向节点的指针,函数参数是二级指针……