2012-10-18 86 views
1

我在C語言中編寫了一個名爲AMESim的仿真軟件,我需要兩維數組管理的幫助。AMESim中malloc/free 2D數組的問題

AMESim與其他仿真軟件(如Simulink或LabView)一樣,將一些圖標放在一個名爲sketch的環境中,並將它們連接在一起,模擬真實系統。在圖標後面有一個C函數,這是我正在寫的部分(好吧,我正在從Fortran中更新它)。該軟件有一個內置的集成器,可以在需要的時間調用各種子模型,並及時管理進程,所以我沒有直接訪問代碼的那部分內容。

我遇到了其中一個子模型存在的問題:該子模型不存在的液壓泵的模型完美地工作,而當連接此模型時,模擬會在一段時間後(1.8之後突然停止)模擬時間的秒數,或集成商大約1970-1980年的呼叫之後)。

該子模型使用應用於二維表面的雷諾方程進行一些重要的摩擦學計算,該矩陣在代碼中用矩陣表示,其尺寸由用戶通過圖形界面決定,然後傳遞給函數作爲參數。在這些基礎上,我需要用動態數組來實現矩陣,或者使用指向數組的指針來實現矩陣(我說的是一個矩陣,但實際上有幾個矩陣,一些整數類型和一些浮點數,還有一些一打單維數組)。矩陣的維數爲(L+Le)*M,而某些數組的維數爲(L+Le),其他數組的維數爲M

遇到問題後,我試圖通過逐步禁用部分代碼來縮小可能的錯誤原因,直到達到下面發佈的狀態。做了各種測試後,我開始明白,問題出在了矩陣/數組的分配上:在某個時刻,malloc將在嘗試分配其中一個矩陣的行時返回一個錯誤(一個NULL)。我嘗試了函數的各種配置和調節分配/釋放的子函數,但是我被這個錯誤困住了。這種情況也會在更改編譯器時發生(我曾嘗試使用Intel和MS VisualC 32位)。

下面是代碼:

#include <math.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include "ameutils.h" //it is a library of AMESim that has various I/O utilities 
#include <malloc.h> 
#include <string.h> 
#include <direct.h> 
#include <errno.h> 

//various functions prototypes 
void allocate_matrix(int ***table, int rows, int columns) ; 
void free_matrix(int*** table, int rows); 
void allocate_matrixd(double ***table, int rows, int columns) ; 
void free_matrixd(double*** table, int rows); 

//bla bla check of parameters and so on 

//this is my main function 
void barreldin27wpprova_(\*bla bla, there are a lot of parameters 
for the calculation that I will skip */ , 
double *rp, //array with real parameters chosen by the user 
int *ip, //array with integer parameters 
double *c, //array with static double that are saved between calls of the function 
int ic[6] //array with static int 
) 
{ 

int loop, i; 
double *Xdib=NULL, *Xwib=NULL, *Xddb=NULL, *Xwdb=NULL; 
double **MatH=NULL, **MatPdim=NULL, **Matx=NULL, **Maty=NULL, **DummyMat=NULL, **MatZp=NULL; 
int **DummyMatInt=NULL, **Matrixt=NULL, **Matrixtn=NULL, **Matrixp=NULL, **Matrixpn=NULL; 
double *VectR=NULL, *DummyL=NULL, *DummyM=NULL, *tetar=NULL, *tetag=NULL, *radim=NULL; 
//these are all of my arrays 

//allocation of dynamic blocks 
    allocate_matrix(&DummyMatInt,(L+Le),M); 
     //repeat for all int matrices 
    allocate_matrixd(&Matx,(L+Le),M); 
     //repeat for all double matrices 

//the program stops with an error from malloc during one of these allocations 

    VectR= malloc((L+Le) * sizeof(double)); 
    if (VectR == NULL) { 
    amefprintf(stdout,"Error in allocation of VectR\n"); //amefprintf is internal 
          of AMESim, the same as fprintf 
    AmeExit(1); //exit function of AMESim 
    } 
    //repeated for all dynamic arrays, then initialized to 0.e0 with "for" cycles 

//a lot of calculation and subfunctions, that are all disabled in this example; function outputs 
    are set to zero 

//Deallocation of dynamic blocks 
free_matrix(&DummyMatInt, (L+Le)); //repeated for all int matrices 
free_matrixd(&Matx, (L+Le));   //repeated for all double matrices 
free(VectR); VectR =NULL;    //repeated for all arrays 
} 

這些是分配/釋放這兩個功能,空間的原因,我只會寫整數的:

void allocate_matrix(int ***table, int rows, int columns) 
{ 
int i,j; 

*table = malloc(rows * sizeof **table); 
    if (*table == NULL) { 
    amefprintf(stdout,"Error in memory allocation array of pointers\n"); 
    AmeExit(1); 
    } 

for (i = 0; i < rows; i++) { 
    (*table)[i] = malloc(columns * sizeof *(*table)[i]); 
    if ((*table)[i] == NULL) { 
     amefprintf(stdout,"Error in memory allocation row %d \n",i); 
     AmeExit(1); 
     } 
    for (j=0; j < columns; j++) { 
     (*table)[i][j] = 0; 
    } 
    } 

} 

void free_matrix(int*** table, int rows) 
{ 
int i; 
for (i = 0; i < rows; i++) 
    { 
    free ((*table)[i]); 
    (*table)[i] = NULL; 
    } 
free (*table); 
*table = NULL; 
return; 
} 

我寫檢查我弄亂了所有引用/解引用指針的東西,並更好地理解如何控制堆的可用空間。我認爲這個錯誤的另一個解釋(我認爲這應該被視爲最後一個資源)是軟件集成商存在一些未知錯誤,但它肯定很難驗證。

+1

爲什麼你需要分開分配每行?這樣做可能不太理想,並增加內存碎片。內存碎片是malloc()無法返回更多內存的原因。 – ydroneaud

+0

@ydroneaud我想你建議分配一些像'Matrix = malloc((L + Le)* M * sizeof(double)); '。但是,我必須用'Matrix [i * ncolumns + j]'調用矩陣的一個元素,這是非常容易出錯的,並且與所有其他代碼的邏輯相反。而且,即使這只是一種感覺,我認爲這不是錯誤的原因。 – crisdarca

+0

當malloc()返回NULL時,您的系統無法爲您的程序提供更多內存。要麼你有碎片問題或內存泄漏。嘗試使用'valgrind'(使用選項'--track-origins = yes') – ydroneaud

回答

0

原來,參數Le未正確初始化(它在分配數組後被初始化)。

因此,在分配時它有一個臨時值(比如說20),分配一個空間L+20內存塊,而初始化時其值爲0。當free被調用時,它只釋放了L+0內存塊,導致在程序的長時間運行期間內存泄漏。

不幸的是,AMESim的結構有點複雜,特別是在參數設置方面。此外,Fortran不太容易出現這種類型的錯誤(或者它可能會簡單地跳過它們),IMO,因此在從一個到另一個的轉換過程中,所有這些混亂都顯示出來了......

感謝那些已閱讀/回覆!