我正在清理我的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()
有疑问。我一直都会遇到分段错误。但为什么?我的指针在这个函数中出了什么问题?有人能给我一个暗示我在这种情况下如何用指针工作吗?我几乎可以肯定我的错误存在。
答案 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;
}