为main()

时间:2016-11-30 20:02:56

标签: c pointers struct

我正在清理我的int main()。由于我是C语言的初学者,我曾经在main() - 函数中写下我所有的东西。现在我想将一些我在其他函数中调用的函数放入一个小函数中。

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <myStructs.h> // Here are my structs geo ,tree and par defined
#include <myFunct.h> // Here are my functions

// Structs
geo dom;
tree **root;
par *p;

void settree(tree **root, par *p, geo dom){
     root = malloc(sizeof(tree*));
     *root = calloc(1, sizeof(tree));
     compDom(&dom, p);
     initTree(root, &dom, p);
}

int main (int argc, char **argv){
    int n = 100;
    p = malloc(sizeof(_Particle) * n); // Allocate memory for par
    anop = n;

    // Load particle data
    par *parptr = p;
    getData(parptr, n);

    double T = 20;
    double g = 1;
    for(double h=0; h<T; h+=g){           
        /// Build tree ///
        settree(*root, p, dom);
        /// Integration ///
        ec(root, p, n, g);
        /// Free Memory ///
        freeTree(*root);
        free(root);
    }
    return 0;
}

我对函数settree()有疑问。我一直都会遇到分段错误。但为什么?我的指针在这个函数中出了什么问题?有人能给我一个暗示我在这种情况下如何用指针工作吗?我几乎可以肯定我的错误存在。

1 个答案:

答案 0 :(得分:0)

您已将root声明为全局变量并将其传递给settree函数,如下所示:

settree(root, ...)

您的settree函数看起来像这样(我已将根参数重命名为myroot以区别于全局变量)

 void settree(tree **myroot, par *p, geo dom){
 myroot = malloc(sizeof(tree*));
 *myroot = calloc(1, sizeof(tree));
 compDom(&dom, p);
 initTree(myroot, &dom, p);

}

现在,您将全局变量root作为参数传递给settree()。由于它是settree()的参数,因此它是函数的本地(在堆栈上分配)而不是真正引用全局变量root。当您致电malloc()myroot中的settree()分配内存时,正在分配该地址的本地变量myroot和全局变量root仍然存在不变。因此,在调用settree()之后,当您尝试在root中使用全局变量main时,会出现段错误,因为它尚未初始化。

你可以这样想。如果你有这样的功能:

void do_double(int x) {
    x = x * 2;
}

并从main调用它,如下所示:     int i = 10;     do_double(ⅰ);

i的值保持不变,因为当您调用do_double(i)时,i的堆栈上创建了do_double()的副本,因此do_double()内的任何修改都会{ {1}}不会影响i。相反,如果do_double是这样的:

void do_double(int *x) {
    *x = *x * 2;
}

你这样称呼它:

i = 10;
do_double(&i);

现在,您传递i的地址,而do_double正在写入该地址,因此i正在更新。同样,当您调用settree(root)时,myroot参数对于函数是本地的,并且在那里进行的任何更改都不会影响全局root变量。相反,你需要做这样的事情:

(我会摆脱全局变量root并在main中声明它)

void settree(tree **root, par *p, geo dom){
     *root = calloc(1, sizeof(tree));
     compDom(&dom, p);
     initTree(root, &dom, p);
}

int main (int argc, char **argv){
    int n = 100;
    p = malloc(sizeof(_Particle) * n); // Allocate memory for par
    anop = n;
    tree *root;


    // Load particle data
    par *parptr = p;
    getData(parptr, n);

    double T = 20;
    double g = 1;
    for(double h=0; h<T; h+=g){           
        /// Build tree ///
        settree(&root, p, dom);
       /// Integration ///
       ec(root, p, n, g);
      /// Free Memory ///
      freeTree(root);
   }
return 0;

}