2017-10-06 134 views
0

我是使用C中的malloc的新手。我試圖聲明一個動態數組結構,然後釋放它,類似於2D aray並釋放它。我使用gcc來編譯代碼。聲明和釋放2D動態數組和結構數組

  1. 第一個問題是使用結構陣列的關於,

    struct OPinfo { 
    
         long NLocal; 
    
         double ReFrame,ImFrame,lcl_ReFrame,lcl_ImFrame,lcl_SqFrame; 
    
    }; 
    
    struct OPinfo *OPSTR; 
    
    
    void declare_local_structure() { 
         OPSTR = (struct OPinfo*) malloc(NBinsR * sizeof(struct OPinfo)); 
         int i =0; 
         while(i<NBinsR) { 
           OPSTR[i].NLocal = 0; 
           OPSTR[i].ReFrame = 0.0; 
           OPSTR[i].ImFrame = 0.0; 
           OPSTR[i].lcl_ReFrame = 0.0; 
           OPSTR[i].lcl_ImFrame = 0.0; 
           OPSTR[i].lcl_SqFrame = 0.0; 
           i++; 
         } 
    
    } 
    void free_local_structure() { 
         fprintf(stderr,"%d %d\n",*OPSTR,OPSTR); 
         free(OPSTR); 
    } 
    

表示沒有指針意外的fprintf中(.. OPSTR)部分是給出在declare_local_structure()和free_local_structure(同地址)同時。如果我評論免費(OPSTR)部分,該計劃運作良好。否則,它會運行,並在最後調用free_local_structure()時發出以下錯誤。 *錯誤在`./a.out':無():無效尺寸:0x0000000002d2fd40 *

  • 在同一程序中的另一部分,我使用的2D陣列指針,我宣佈,中

    double **Gxy, **GxyRot; 
    Gxy = (double**) malloc((NBinsXY) * sizeof(double *)); 
    GxyRot = (double**) malloc((NBinsXY) * sizeof(double *)); 
    
    for(j=0; j<NBinsXY; j++) { 
         Gxy[j] = malloc(NBinsXY * sizeof(double)); 
         GxyRot[j] = malloc(NBinsXY * sizeof(double)); 
    } 
    
  • 和自由通過,

    for(l=0;l<NBinsXY;l++) { 
         free(Gxy[l]); 
         free(GxyRot[l]); 
    } 
    
    free(Gxy); 
    free(GxyRot); 
    

    這再次給SA我上面的錯誤,但如果我免費,

    free(*Gxy); 
    free(*GxyRot); 
    free(Gxy); 
    free(GxyRot); 
    

    該程序運行沒有錯誤。

    錯誤在哪裏?我嘗試了「valgrind」,但無法理解輸出。另一點是程序在編譯C99時出錯。 gcc -std=c99 *.c headers/*.h -lm

    +2

    什麼是你的調用'declare_local_structure'和'free_local_structure'之間*做*?也許你在代碼中寫出了沒有向​​我們展示的內容?至於Valgrind,使用調試信息(在構建時添加'-g'標誌)並重新運行,Valgrind將能夠顯示它找到的問題的源文件和行號信息。如果你無法弄清楚,那麼編輯你的問題以包含Valgrind的完整複製粘貼(作爲文本)輸出。 –

    +2

    將'-Wall -Wextra'添加到GCC命令行時會得到什麼警告?至少應該有一個,因爲你的'fprintf'調用是無效的(你不能將'* OPSTR'傳遞給'fprintf',並期望它正確地處理事情,特別是當你告訴它你傳遞一個數字時)我懷疑是什麼導致了這個問題。 –

    +0

    感謝您的「-g」建議。二維數組聲明中的Valarind錯誤。 「initialize_declare.c:32」是數組Gxy和GxyRot,大小爲8的無效讀取 == 2138 ==在0x401864:calculate_bin(calculation.c:125) == 2138 == by 0x401E36:calculate_for_frame(calculation.c: 168) == 2138 == by 0x40359E:main(main_function.c:72) == 2138 ==地址0x652c710在一個大小爲8,000的塊後分配16個字節 == 2138 ==在0x4C2DB9D:malloc( vg_replace_malloc.c:299) == 2138 == by 0x402CCA:declare_arrays(initialize_declare.c:32) == 2138 == by 0x403516:main(main_function.c:58) – haphaZard

    回答

    0

    我同意上面的意見,關於積極使用調試器,因爲它會提供有關問題性質和位置的詳細信息。

    關於使用C中[m][c]alloc時用C分配內存,(並不適用於C++)一般情況下,是(雖然仍然嚴格爭論)it not necessary (or recommended)你投的回報。例如,以下內容:

    Gxy = (double**) malloc((NBinsXY) * sizeof(double *)); 
    

    應該寫成:

    Gxy = malloc((NBinsXY) * sizeof(double *)); 
    if(Gxy)//and always test for success before using pointers created using malloc/calloc 
    { 
        ... 
    

    關於釋放,規則是每次調用[m][c]alloc()必須有相應的同等數量的調用來free(...)。由於您使用的是循環分配內存,是有意義的使用一個免費期間以及:

    for(j=0; j<NBinsXY; j++) { 
        free(Gxy[j]); 
        free(GxyRot[j]); 
    } 
    free(Gxy); 
    free(GxyRot); 
    
    +0

    根據你的要求,投射回歸可能會或可能不會是更好的風格。但是,它不會造成這種錯誤。 –

    +0

    @DanielH - 儘管仍然經常爭論,但是在C中拋出或不拋棄calloc的返回問題並不是風格問題。這更多的是掩蓋在嘗試創建內存時可能發生的問題。這隻適用於'C',而不是'C++',建議在這裏建立返回。 – ryyker

    +0

    在你最後的代碼示例中,在取消引用基於它們的指針之後,檢查'Gxy'和'GxyRot'。如果你以後不打算檢查它們,那麼根本不值得檢查它們。 –