2016-11-30 53 views
-1

我正在清理我的int main()。因爲我是C的初學者,所以我用main()函數編寫了所有的東西。現在我想把我在其他函數中調用的一些函數集成到一個小函數中。爲main()以外的struct和call函數分配內存

#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

您已經聲明根作爲一個全局變量,並將其傳遞給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); 

}

現在,你是路過的全局變量rootsettree()作爲參數。由於它是settree()的一個參數,因此該函數在本地(在堆棧上分配),而不是真正指向全局變量root。當您撥打malloc()myroot分配內存settree()時,它是本地變量myroot正在分配該地址和全局變量root保持不變。因此,調用settree()後,當您嘗試使用main中的全局變量root時,您會收到段錯誤,因爲它尚未初始化。

你可以這樣想。如果你有這樣的功能:

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

,並從主這樣稱呼它: INT I = 10; do_double(i);

i值保持不變,因爲當你叫do_double(i)i一個副本的do_double()在棧上創建的,所以裏面do_double()任何修改將不會影響i。相反,如果do_double是這樣的:

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

你這樣稱呼它:

i = 10; 
do_double(&i); 

現在,你是路過的i地址,do_double被寫入該地址,所以i越來越更新。同樣,當您撥打settree(root)時,myroot參數對於該功能而言是本地的,並且在此處所做的任何更改都不會影響全局root變量。相反,你需要做這樣的事情:

(我會擺脫全局變量根並宣佈,這裏面主要)

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; 

}

+0

這並沒有解決我的問題。我仍然得到seg。故障。該錯誤可能是其他地方。你有另一個想法嗎? – Samuel

+0

您是否有來自segfault的堆棧跟蹤? –

+0

我不知道該怎麼做。抱歉。正如我所說的,我是C初學者,控制檯只顯示'Segmentation fault'。如果我將'settree()'的內容放在'main()'中,而不是程序工作。 – Samuel