[英]Malloc function in C errors with pointers
I've create this function that's supposed to create a randomly generated binary tree, it works fine but at the end of the function the root == NULL, i can't understand why! 我已经创建了应该创建一个随机生成的二叉树的函数,它可以正常工作,但是在函数末尾,根== NULL,我不明白为什么!
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
#define MAX_B 7
typedef struct _ramo{
int nbanane;
struct _ramo *dx;
struct _ramo *sx;
}ramo;
void creaAlbero(ramo *root, int n){
printf("%d\n",n);
root = malloc(sizeof(ramo));
root->nbanane=rand()%MAX_B;
printf("BANANA! %d\n",root->nbanane);
root->dx=NULL;
root->sx=NULL;
if ((int)(rand()%n)==0)
creaAlbero(root->dx, n+1);
if ((int)(rand()%n)==0)
creaAlbero(root->sx, n+1);
}
int main(){
srand((unsigned int)time(NULL));
ramo *root=NULL;
creaAlbero(root, 1);
if (root==NULL) {
printf("EMPTY!!");
}
return 0;
}
You set root
to NULL
: 您将
root
设置为NULL
:
ramo *root=NULL;
then pass a copy of it to creaAlbero()
: 然后将其副本传递给
creaAlbero()
:
creaAlbero(root, 1);
which modifies the copy 修改副本
root = malloc(sizeof(ramo));
then returns. 然后返回。 The original
root
is still NULL
, because nothing changed it. 原始
root
仍然为NULL
,因为没有任何更改。
Consider returning root
from creaAlbero()
: 考虑从
creaAlbero()
返回root
:
ramo * creaAlbero(int n){
printf("%d\n",n);
ramo *root = malloc(sizeof(ramo));
root->nbanane=rand()%MAX_B;
printf("BANANA! %d\n",root->nbanane);
root->dx=NULL;
root->sx=NULL;
if ((int)(rand()%n)==0)
root->dx = creaAlbero(n+1);
if ((int)(rand()%n)==0)
root->sx = creaAlbero(n+1);
return root;
}
int main(){
srand((unsigned int)time(NULL));
ramo *root=NULL;
root = creaAlbero(1);
if (root==NULL) {
printf("EMPTY!!");
}
return 0;
}
Example: https://ideone.com/dXiv8A 示例: https : //ideone.com/dXiv8A
creaAlbero(ramo *root, int n)
is a function that takes a copy of a pointer to a ramo
. creaAlbero(ramo *root, int n)
是一个函数,它获取指向ramo
的指针的副本。 It then proceeds to do stuff with this copy of the pointer, and then returns. 然后,它继续使用此指针副本进行操作,然后返回。
main
then looks a the value of the origonal root
variable, which was (obviously) never changed. 然后
main
会查找原始 root
变量的值,该值(显然)从未改变。
If you want a function to modify a value that's passed in, you must pass the object by pointer. 如果要让函数修改传入的值,则必须通过指针传递对象。 To clarify: if you want a function to modify a pointer, the function must take as a parameter a pointer to a pointer to a thing:
需要说明的是:如果要让函数修改指针,则该函数必须将指向事物的指针的指针作为参数:
void creaAlbero(ramo **rootptr, int n){ //pass rootptr by pointer
*rootptr = malloc(sizeof(ramo)); //modify pointer pointed at by rootptr
ramo* root = *rootptr; //make local copy of value for ease of use
//rest of your code here
}
int main(){
ramo *root=NULL;
creaAlbero(&root, 1); //pass by pointer
Paul Roub's answer also suggests another excellent idea: return the ramo*
from the function instead of taking it as a mutable parameter. 保罗·鲁布(Paul Roub)的答案还提出了另一个绝妙的主意:从函数返回
ramo*
而不是将其作为可变参数。 It's simpler and more intuitive by far. 到目前为止,它更简单,更直观。
root
is passed to creaAlbero
by value. root
按值传递给creaAlbero
。 Any changes made to root
in creaAlbero
are only local modifications. 对
creaAlbero
中的root
所做的任何更改仅是本地修改。 They don't change the value of root
in main. 它们不会更改main中
root
的值。 A better alternative would be to change the signature of creaAlbero
to: 更好的选择是将
creaAlbero
的签名creaAlbero
为:
ramo* creaAlbero(int n){
printf("%d\n",n);
ramo* root = malloc(sizeof(ramo));
root->nbanane=rand()%MAX_B;
printf("BANANA! %d\n",root->nbanane);
root->dx=NULL;
root->sx=NULL;
if ((int)(rand()%n)==0)
root->dx = creaAlbero(n+1);
if ((int)(rand()%n)==0)
root->sx = creaAlbero(n+1);
return root;
}
and change the usage to: 并将用法更改为:
int main(){
srand((unsigned int)time(NULL));
ramo *root = creaAlbero(1);
if (root==NULL) {
printf("EMPTY!!");
}
return 0;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.