带有指针的 C 错误中的 Malloc 函数



我创建了这个函数,它应该创建一个随机生成的二叉树,它工作正常,但在函数结束时根 == 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("%dn",n);
    root = malloc(sizeof(ramo));
    root->nbanane=rand()%MAX_B;
    printf("BANANA! %dn",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;
}

您将root设置为 NULL

ramo *root=NULL;

然后将它的副本传递给creaAlbero()

creaAlbero(root, 1);

修改副本

root = malloc(sizeof(ramo));

然后返回。原来的root仍然NULL,因为没有什么改变它。

考虑从creaAlbero()返回root

ramo * creaAlbero(int n){
  printf("%dn",n);
  ramo *root = malloc(sizeof(ramo));
  root->nbanane=rand()%MAX_B;
  printf("BANANA! %dn",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;
}

示例:https://ideone.com/dXiv8A

creaAlbero(ramo *root, int n)是一个函数,它复制指向ramo的指针。 然后,它继续使用此指针副本执行操作,然后返回。 然后main查找原始root变量的值,该变量(显然)从未更改过。

如果希望函数修改传入的值,则必须通过指针传递对象。 澄清一下:如果你想让一个函数修改一个指针,该函数必须将一个指向事物的指针作为参数:

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 的回答还提出了另一个好主意:从函数返回ramo*,而不是将其作为可变参数。 到目前为止,它更简单、更直观。

root按值传递给creaAlbero。在creaAlbero中对root所做的任何更改都只是本地修改。它们不会更改 main 中root的值。更好的选择是将creaAlbero的签名更改为:

ramo* creaAlbero(int n){
   printf("%dn",n);
   ramo* root = malloc(sizeof(ramo));
   root->nbanane=rand()%MAX_B;
   printf("BANANA! %dn",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 = creaAlbero(1);
   if (root==NULL) {
      printf("EMPTY!!");
   }
   return 0;
}

相关内容

  • 没有找到相关文章

最新更新